github.com/songzhibin97/gkit@v1.2.13/tools/bind/default_validator.go (about) 1 package bind 2 3 import ( 4 "fmt" 5 "reflect" 6 "strings" 7 "sync" 8 9 "github.com/go-playground/validator/v10" 10 ) 11 12 type defaultValidator struct { 13 once sync.Once 14 validate *validator.Validate 15 } 16 17 type sliceValidateError []error 18 19 func (err sliceValidateError) Error() string { 20 var errMsgs []string 21 for i, e := range err { 22 if e == nil { 23 continue 24 } 25 errMsgs = append(errMsgs, fmt.Sprintf("[%d]: %s", i, e.Error())) 26 } 27 return strings.Join(errMsgs, "\n") 28 } 29 30 var _ StructValidator = &defaultValidator{} 31 32 // ValidateStruct receives any kind of type, but only performed struct or pointer to struct type. 33 func (v *defaultValidator) ValidateStruct(obj interface{}) error { 34 if obj == nil { 35 return nil 36 } 37 38 value := reflect.ValueOf(obj) 39 switch value.Kind() { 40 case reflect.Ptr: 41 return v.ValidateStruct(value.Elem().Interface()) 42 case reflect.Struct: 43 return v.validateStruct(obj) 44 case reflect.Slice, reflect.Array: 45 count := value.Len() 46 validateRet := make(sliceValidateError, 0) 47 for i := 0; i < count; i++ { 48 if err := v.ValidateStruct(value.Index(i).Interface()); err != nil { 49 validateRet = append(validateRet, err) 50 } 51 } 52 if len(validateRet) == 0 { 53 return nil 54 } 55 return validateRet 56 default: 57 return nil 58 } 59 } 60 61 // validateStruct receives struct type 62 func (v *defaultValidator) validateStruct(obj interface{}) error { 63 v.lazyinit() 64 return v.validate.Struct(obj) 65 } 66 67 // Engine returns the underlying validator engine which powers the default 68 // Validator instance. This is useful if you want to register custom validations 69 // or struct level validations. See validator GoDoc for more info - 70 // https://godoc.org/gopkg.in/go-playground/validator.v8 71 func (v *defaultValidator) Engine() interface{} { 72 v.lazyinit() 73 return v.validate 74 } 75 76 func (v *defaultValidator) lazyinit() { 77 v.once.Do(func() { 78 v.validate = validator.New() 79 v.validate.SetTagName("binding") 80 }) 81 }