github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/gin/binding/default_validator.go (about)

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