| 29 | var validatorType = reflect.TypeFor[CustomValidator]() |
| 30 | |
| 31 | func ValidateWithCustomValidator(v reflect.Value) error { |
| 32 | vt := v.Type() |
| 33 | if v.Kind() == reflect.Pointer { |
| 34 | elemType := vt.Elem() |
| 35 | if vt.Implements(validatorType) { |
| 36 | if v.IsNil() { |
| 37 | return reflect.New(elemType).Interface().(CustomValidator).Validate() |
| 38 | } |
| 39 | return v.Interface().(CustomValidator).Validate() |
| 40 | } |
| 41 | if elemType.Implements(validatorType) { |
| 42 | return v.Elem().Interface().(CustomValidator).Validate() |
| 43 | } |
| 44 | } else if vt.PkgPath() != "" { // not a builtin type |
| 45 | // prioritize pointer method |
| 46 | if v.CanAddr() { |
| 47 | vAddr := v.Addr() |
| 48 | if vAddr.Type().Implements(validatorType) { |
| 49 | return vAddr.Interface().(CustomValidator).Validate() |
| 50 | } |
| 51 | } |
| 52 | // fallback to value method |
| 53 | if vt.Implements(validatorType) { |
| 54 | return v.Interface().(CustomValidator).Validate() |
| 55 | } |
| 56 | } |
| 57 | return nil |
| 58 | } |