gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

default_validator.go (2304B)


      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 }