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  }