default_validator.go 2.0 KB

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