...

Source file src/github.com/gin-gonic/gin/binding/default_validator.go

Documentation: github.com/gin-gonic/gin/binding

     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 SliceValidationError []error
    22  
    23  // Error concatenates all error elements in SliceValidationError into a single string separated by \n.
    24  func (err SliceValidationError) Error() string {
    25  	n := len(err)
    26  	switch n {
    27  	case 0:
    28  		return ""
    29  	default:
    30  		var b strings.Builder
    31  		if err[0] != nil {
    32  			fmt.Fprintf(&b, "[%d]: %s", 0, err[0].Error())
    33  		}
    34  		if n > 1 {
    35  			for i := 1; i < n; i++ {
    36  				if err[i] != nil {
    37  					b.WriteString("\n")
    38  					fmt.Fprintf(&b, "[%d]: %s", i, err[i].Error())
    39  				}
    40  			}
    41  		}
    42  		return b.String()
    43  	}
    44  }
    45  
    46  var _ StructValidator = (*defaultValidator)(nil)
    47  
    48  // ValidateStruct receives any kind of type, but only performed struct or pointer to struct type.
    49  func (v *defaultValidator) ValidateStruct(obj any) error {
    50  	if obj == nil {
    51  		return nil
    52  	}
    53  
    54  	value := reflect.ValueOf(obj)
    55  	switch value.Kind() {
    56  	case reflect.Ptr:
    57  		return v.ValidateStruct(value.Elem().Interface())
    58  	case reflect.Struct:
    59  		return v.validateStruct(obj)
    60  	case reflect.Slice, reflect.Array:
    61  		count := value.Len()
    62  		validateRet := make(SliceValidationError, 0)
    63  		for i := 0; i < count; i++ {
    64  			if err := v.ValidateStruct(value.Index(i).Interface()); err != nil {
    65  				validateRet = append(validateRet, err)
    66  			}
    67  		}
    68  		if len(validateRet) == 0 {
    69  			return nil
    70  		}
    71  		return validateRet
    72  	default:
    73  		return nil
    74  	}
    75  }
    76  
    77  // validateStruct receives struct type
    78  func (v *defaultValidator) validateStruct(obj any) error {
    79  	v.lazyinit()
    80  	return v.validate.Struct(obj)
    81  }
    82  
    83  // Engine returns the underlying validator engine which powers the default
    84  // Validator instance. This is useful if you want to register custom validations
    85  // or struct level validations. See validator GoDoc for more info -
    86  // https://pkg.go.dev/github.com/go-playground/validator/v10
    87  func (v *defaultValidator) Engine() any {
    88  	v.lazyinit()
    89  	return v.validate
    90  }
    91  
    92  func (v *defaultValidator) lazyinit() {
    93  	v.once.Do(func() {
    94  		v.validate = validator.New()
    95  		v.validate.SetTagName("binding")
    96  	})
    97  }
    98  

View as plain text