| 207 | } |
| 208 | |
| 209 | func In(needle any, array any) bool { |
| 210 | if array == nil { |
| 211 | return false |
| 212 | } |
| 213 | v := reflect.ValueOf(array) |
| 214 | |
| 215 | switch v.Kind() { |
| 216 | |
| 217 | case reflect.Array, reflect.Slice: |
| 218 | for i := 0; i < v.Len(); i++ { |
| 219 | value := v.Index(i) |
| 220 | if value.IsValid() { |
| 221 | if Equal(value.Interface(), needle) { |
| 222 | return true |
| 223 | } |
| 224 | } |
| 225 | } |
| 226 | return false |
| 227 | |
| 228 | case reflect.Map: |
| 229 | var value reflect.Value |
| 230 | if needle == nil { |
| 231 | value = v.MapIndex(reflect.Zero(v.Type().Key())) |
| 232 | } else { |
| 233 | value = v.MapIndex(reflect.ValueOf(needle)) |
| 234 | } |
| 235 | if value.IsValid() { |
| 236 | return true |
| 237 | } |
| 238 | return false |
| 239 | |
| 240 | case reflect.Struct: |
| 241 | n := reflect.ValueOf(needle) |
| 242 | if !n.IsValid() || n.Kind() != reflect.String { |
| 243 | panic(fmt.Sprintf("cannot use %T as field name of %T", needle, array)) |
| 244 | } |
| 245 | field, ok := v.Type().FieldByName(n.String()) |
| 246 | if !ok || !field.IsExported() || field.Tag.Get("expr") == "-" { |
| 247 | return false |
| 248 | } |
| 249 | value := v.FieldByIndex(field.Index) |
| 250 | if value.IsValid() { |
| 251 | return true |
| 252 | } |
| 253 | return false |
| 254 | |
| 255 | case reflect.Ptr: |
| 256 | value := v.Elem() |
| 257 | if value.IsValid() { |
| 258 | return In(needle, value.Interface()) |
| 259 | } |
| 260 | return false |
| 261 | } |
| 262 | |
| 263 | panic(fmt.Sprintf(`operator "in" not defined on %T`, array)) |
| 264 | } |
| 265 | |
| 266 | func Len(a any) int { |