github.com/yandex/pandora@v0.5.32/core/config/validator.go (about)

     1  package config
     2  
     3  import (
     4  	"github.com/pkg/errors"
     5  	validator "gopkg.in/bluesuncorp/validator.v9"
     6  )
     7  
     8  var validations = []struct {
     9  	key string
    10  	val validator.Func
    11  }{
    12  	{"min-time", MinTimeValidation},
    13  	{"max-time", MaxTimeValidation},
    14  	{"min-size", MinSizeValidation},
    15  	{"max-size", MaxSizeValidation},
    16  }
    17  
    18  var stringValidations = []struct {
    19  	key string
    20  	val StringValidation
    21  }{
    22  	{"endpoint", EndpointStringValidation},
    23  	{"url-path", URLPathStringValidation},
    24  }
    25  
    26  var defaultValidator = newValidator()
    27  
    28  func Validate(value interface{}) error {
    29  	return errors.WithStack(defaultValidator.Struct(value))
    30  }
    31  
    32  func newValidator() *validator.Validate {
    33  	validate := validator.New()
    34  	validate.SetTagName("validate")
    35  	for _, val := range validations {
    36  		_ = validate.RegisterValidation(val.key, val.val)
    37  	}
    38  	for _, val := range stringValidations {
    39  		_ = validate.RegisterValidation(val.key, StringToAbstractValidation(val.val))
    40  	}
    41  	return validate
    42  }
    43  
    44  // RegisterCustom used to set custom validation check hooks on specific types,
    45  // that will be called on such type validation, even if it is nested field.
    46  func RegisterCustom(v CustomValidation, types ...interface{}) (_ struct{}) {
    47  	if len(types) < 1 {
    48  		panic("should be registered for at least one type")
    49  	}
    50  	defaultValidator.RegisterStructValidation(func(sl validator.StructLevel) {
    51  		v(structLevelHandle{sl})
    52  	}, types...)
    53  	return
    54  }
    55  
    56  type StringValidation func(value string) bool
    57  
    58  // StringToAbstractValidation wraps StringValidation into validator.Func.
    59  func StringToAbstractValidation(sv StringValidation) validator.Func {
    60  	return func(fl validator.FieldLevel) bool {
    61  		if strVal, ok := fl.Field().Interface().(string); ok {
    62  			return sv(strVal)
    63  		}
    64  		return false
    65  	}
    66  }
    67  
    68  type ValidateHandle interface {
    69  	Value() interface{}
    70  	ReportError(field, reason string)
    71  }
    72  
    73  type CustomValidation func(h ValidateHandle)
    74  
    75  type structLevelHandle struct{ validator.StructLevel }
    76  
    77  var _ ValidateHandle = structLevelHandle{}
    78  
    79  func (sl structLevelHandle) Value() interface{} { return sl.Current().Interface() }
    80  func (sl structLevelHandle) ReportError(field, reason string) {
    81  	sl.StructLevel.ReportError(nil, field, "", reason, "")
    82  }