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 }