mirror of
https://github.com/yusing/godoxy.git
synced 2026-01-14 07:33:36 +01:00
66 lines
1.4 KiB
Go
66 lines
1.4 KiB
Go
package serialization
|
|
|
|
import (
|
|
"reflect"
|
|
|
|
"github.com/go-playground/validator/v10"
|
|
gperr "github.com/yusing/goutils/errs"
|
|
)
|
|
|
|
var validate = validator.New()
|
|
|
|
var ErrValidationError = gperr.New("validation error")
|
|
|
|
func Validator() *validator.Validate {
|
|
return validate
|
|
}
|
|
|
|
func MustRegisterValidation(tag string, fn validator.Func) {
|
|
err := validate.RegisterValidation(tag, fn)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
type CustomValidator interface {
|
|
Validate() gperr.Error
|
|
}
|
|
|
|
var validatorType = reflect.TypeFor[CustomValidator]()
|
|
|
|
func ValidateWithCustomValidator(v reflect.Value) gperr.Error {
|
|
if v.Kind() == reflect.Pointer {
|
|
if v.IsNil() {
|
|
// return nil
|
|
return validateWithValidator(reflect.New(v.Type().Elem()))
|
|
}
|
|
if v.Type().Implements(validatorType) {
|
|
return v.Interface().(CustomValidator).Validate()
|
|
}
|
|
return validateWithValidator(v.Elem())
|
|
} else {
|
|
vt := v.Type()
|
|
if vt.PkgPath() != "" { // not a builtin type
|
|
// prioritize pointer method
|
|
if v.CanAddr() {
|
|
vAddr := v.Addr()
|
|
if vAddr.Type().Implements(validatorType) {
|
|
return vAddr.Interface().(CustomValidator).Validate()
|
|
}
|
|
}
|
|
// fallback to value method
|
|
if vt.Implements(validatorType) {
|
|
return v.Interface().(CustomValidator).Validate()
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func validateWithValidator(v reflect.Value) gperr.Error {
|
|
if v.Type().Implements(validatorType) {
|
|
return v.Interface().(CustomValidator).Validate()
|
|
}
|
|
return nil
|
|
}
|