Documentation ¶
Overview ¶
Each Validator have at least two process methods, one for 'Parsing' and one for 'Validating'.
In 'Parsing' stage, we call validator as 'ValidatorCreator', and it will be register to some 'ValidatorMgr' for caching.
Parsing ¶
There are common 'Rule DSL' below:
// simple @name // with parameters @name<param1> @name<param1,param2> // with ranges @name[from, to) @name[length] // with values @name{VALUE1,VALUE2,VALUE3} @name{%v} // with regexp @name/\d+/ // optional and default value @name? @name = value @name = 'some string value' // composes @map<@string[1,10],@string{A,B,C}> @map<@string[1,10],@string/\d+/>[0,10]
Then the parsed rule will be transform to special validators:
Validating ¶
We can create validator by 'Rule DSL', and also can configure them by validator struct field as conditions. Then call the method `Validate(v interface{}) error` to do value validations.
Index ¶
- Constants
- Variables
- func ContextWithNamedTagKey(ctx context.Context, namedTagKey string) context.Context
- func ContextWithValidatorMgr(c context.Context, validatorMgr ValidatorMgr) context.Context
- func MaxInt(bitSize uint) int64
- func MaxUint(bitSize uint) uint64
- func MinInt(bitSize uint) int64
- func NamedKeyFromContext(ctx context.Context) string
- func RangeFromUint(min uint64, max *uint64) []*rules.RuleLit
- func ToMarshalledText(v interface{}) string
- func UintRange(typ string, bitSize uint, ranges ...*rules.RuleLit) (uint64, *uint64, error)
- type ErrorSet
- func (es *ErrorSet) AddErr(err error, keyPathNodes ...interface{})
- func (es *ErrorSet) Each(cb func(fieldErr *FieldError))
- func (es *ErrorSet) Err() error
- func (es *ErrorSet) Error() string
- func (es *ErrorSet) Flatten() *ErrorSet
- func (es *ErrorSet) Len() int
- func (es *ErrorSet) ToErrorFields() statuserror.ErrorFields
- type FieldError
- type FloatValidator
- func (FloatValidator) Names() []string
- func (FloatValidator) New(ctx context.Context, rule *Rule) (Validator, error)
- func (validator *FloatValidator) SetDefaults()
- func (validator *FloatValidator) String() string
- func (validator *FloatValidator) TypeCheck(rule *Rule) error
- func (validator *FloatValidator) Validate(v interface{}) error
- type IntValidator
- func (IntValidator) Names() []string
- func (IntValidator) New(ctx context.Context, rule *Rule) (Validator, error)
- func (validator *IntValidator) SetDefaults()
- func (validator *IntValidator) String() string
- func (validator *IntValidator) TypeCheck(rule *Rule) error
- func (validator *IntValidator) Validate(v interface{}) error
- type KeyPath
- type Location
- type MapValidator
- func (MapValidator) Names() []string
- func (validator *MapValidator) New(ctx context.Context, rule *Rule) (Validator, error)
- func (validator *MapValidator) String() string
- func (validator *MapValidator) Validate(v interface{}) error
- func (validator *MapValidator) ValidateReflectValue(rv reflect.Value) error
- type MissingRequired
- type MultipleOfError
- type NotInEnumError
- type NotMatchError
- type OutOfRangeError
- type PreprocessStage
- type Rule
- type RuleModifier
- type RuleProcessor
- type SliceValidator
- func (SliceValidator) Names() []string
- func (SliceValidator) New(ctx context.Context, rule *Rule) (Validator, error)
- func (validator *SliceValidator) String() string
- func (validator *SliceValidator) Validate(v interface{}) error
- func (validator *SliceValidator) ValidateReflectValue(rv reflect.Value) error
- type StrLenMode
- type StrfmtValidator
- func (validator *StrfmtValidator) Names() []string
- func (validator StrfmtValidator) New(ctx context.Context, rule *Rule) (Validator, error)
- func (validator *StrfmtValidator) String() string
- func (validator *StrfmtValidator) TypeCheck(rule *Rule) error
- func (validator *StrfmtValidator) Validate(v interface{}) error
- type StringValidator
- type StructValidator
- func (StructValidator) Names() []string
- func (validator *StructValidator) New(ctx context.Context, rule *Rule) (Validator, error)
- func (validator *StructValidator) String() string
- func (validator *StructValidator) Validate(v interface{}) error
- func (validator *StructValidator) ValidateReflectValue(rv reflect.Value) error
- type UintValidator
- func (UintValidator) Names() []string
- func (UintValidator) New(ctx context.Context, rule *Rule) (Validator, error)
- func (validator *UintValidator) SetDefaults()
- func (validator *UintValidator) String() string
- func (validator *UintValidator) TypeCheck(rule *Rule) error
- func (validator *UintValidator) Validate(v interface{}) error
- type UnsupportedTypeError
- type Validator
- type ValidatorCreator
- type ValidatorFactory
- func (f *ValidatorFactory) Compile(ctx context.Context, ruleBytes []byte, typ typesutil.Type, ...) (validator Validator, err error)
- func (f *ValidatorFactory) MustCompile(ctx context.Context, rule []byte, typ typesutil.Type, ...) Validator
- func (f *ValidatorFactory) Register(validators ...ValidatorCreator)
- type ValidatorLoader
- type ValidatorMgr
Examples ¶
Constants ¶
const ( TagValidate = "validate" TagDefault = "default" TagErrMsg = "errMsg" )
Variables ¶
var ( TargetFloatValue = "float value" TargetDecimalDigitsOfFloatValue = "decimal digits of float value" TargetTotalDigitsOfFloatValue = "total digits of float value" )
var (
TargetIntValue = "int value"
)
var (
TargetMapLength = "map length"
)
var (
TargetSliceLength = "slice length"
)
var (
TargetStringLength = "string length"
)
var (
TargetUintValue = "uint value"
)
var ValidatorMgrDefault = NewValidatorFactory()
Functions ¶
func ContextWithNamedTagKey ¶
func ContextWithValidatorMgr ¶
func ContextWithValidatorMgr(c context.Context, validatorMgr ValidatorMgr) context.Context
func NamedKeyFromContext ¶
func ToMarshalledText ¶
func ToMarshalledText(v interface{}) string
Types ¶
type ErrorSet ¶
type ErrorSet struct {
// contains filtered or unexported fields
}
Example ¶
subErrSet := NewErrorSet("") subErrSet.AddErr(fmt.Errorf("err"), "PropA") subErrSet.AddErr(fmt.Errorf("err"), "PropB") errSet := NewErrorSet("") errSet.AddErr(fmt.Errorf("err"), "Key") errSet.AddErr(subErrSet.Err(), "Key", 1) errSet.AddErr(NewErrorSet("").Err(), "Key", 1) fmt.Println(errSet.Flatten().Len()) fmt.Println(errSet)
Output: 3 Key err Key[1].PropA err Key[1].PropB err
func NewErrorSet ¶
func NewErrorSet(paths ...interface{}) *ErrorSet
func (*ErrorSet) Each ¶
func (es *ErrorSet) Each(cb func(fieldErr *FieldError))
func (*ErrorSet) ToErrorFields ¶ added in v1.21.1
func (es *ErrorSet) ToErrorFields() statuserror.ErrorFields
type FieldError ¶
type FloatValidator ¶
type FloatValidator struct { MaxDigits uint DecimalDigits *uint Minimum *float64 Maximum *float64 ExclusiveMaximum bool ExclusiveMinimum bool MultipleOf float64 Enums []float64 }
Validator for float32 and float64
Rules:
ranges
@float[min,max] @float[1,10] // value should large or equal than 1 and less or equal than 10 @float(1,10] // value should large than 1 and less or equal than 10 @float[1,10) // value should large or equal than 1 @float[1,) // value should large or equal than 1 @float[,1) // value should less than 1
enumeration
@float{1.1,1.2,1.3} // value should be one of these
multiple of some float value
@float{%multipleOf} @float{%2.2} // value should be multiple of 2.2
max digits and decimal digits. when defined, all values in rule should be under range of them.
@float<MAX_DIGITS,DECIMAL_DIGITS> @float<5,2> // will checkout these values invalid: 1.111 (decimal digits too many), 12345.6 (digits too many)
composes
@float<MAX_DIGITS,DECIMAL_DIGITS>[min,max]
aliases:
@float32 = @float<7> @float64 = @float<15>
func (FloatValidator) Names ¶
func (FloatValidator) Names() []string
func (*FloatValidator) SetDefaults ¶
func (validator *FloatValidator) SetDefaults()
func (*FloatValidator) String ¶
func (validator *FloatValidator) String() string
func (*FloatValidator) TypeCheck ¶
func (validator *FloatValidator) TypeCheck(rule *Rule) error
func (*FloatValidator) Validate ¶
func (validator *FloatValidator) Validate(v interface{}) error
type IntValidator ¶
type IntValidator struct { BitSize uint Minimum *int64 Maximum *int64 MultipleOf int64 ExclusiveMaximum bool ExclusiveMinimum bool Enums []int64 }
Validator for int
Rules:
ranges
@int[min,max] @int[1,10] // value should large or equal than 1 and less or equal than 10 @int(1,10] // value should large than 1 and less or equal than 10 @int[1,10) // value should large or equal than 1 @int[1,) // value should large or equal than 1 and less than the maxinum of int32 @int[,1) // value should less than 1 and large or equal than the mininum of int32 @int // value should less or equal than maxinum of int32 and large or equal than the mininum of int32
enumeration
@int{1,2,3} // should one of these values
multiple of some int value
@int{%multipleOf} @int{%2} // should be multiple of 2
bit size in parameter
@int<8> @int<16> @int<32> @int<64>
composes
@int<8>[1,]
aliases:
@int8 = @int<8> @int16 = @int<16> @int32 = @int<32> @int64 = @int<64>
Tips: for JavaScript https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER
int<53>
func (IntValidator) Names ¶
func (IntValidator) Names() []string
func (*IntValidator) SetDefaults ¶
func (validator *IntValidator) SetDefaults()
func (*IntValidator) String ¶
func (validator *IntValidator) String() string
func (*IntValidator) TypeCheck ¶
func (validator *IntValidator) TypeCheck(rule *Rule) error
func (*IntValidator) Validate ¶
func (validator *IntValidator) Validate(v interface{}) error
type MapValidator ¶
type MapValidator struct { MinProperties uint64 MaxProperties *uint64 KeyValidator Validator ElemValidator Validator }
Validator for map
Rules:
@map<KEY_RULE, ELEM_RULE>[minSize,maxSize] @map<KEY_RULE, ELEM_RULE>[length] @map<@string{A,B,C},@int[0]>[,100]
func (MapValidator) Names ¶
func (MapValidator) Names() []string
func (*MapValidator) String ¶
func (validator *MapValidator) String() string
func (*MapValidator) Validate ¶
func (validator *MapValidator) Validate(v interface{}) error
func (*MapValidator) ValidateReflectValue ¶
func (validator *MapValidator) ValidateReflectValue(rv reflect.Value) error
type MissingRequired ¶
type MissingRequired struct{}
Example ¶
fmt.Println(MissingRequired{})
Output: missing required field
func (MissingRequired) Error ¶
func (MissingRequired) Error() string
type MultipleOfError ¶
type MultipleOfError struct { Target string Current interface{} MultipleOf interface{} }
Example ¶
fmt.Println(&MultipleOfError{ Target: "int value", Current: "11", MultipleOf: 2, })
Output: int value should be multiple of 2, but got invalid value 11
func (*MultipleOfError) Error ¶
func (e *MultipleOfError) Error() string
type NotInEnumError ¶
type NotInEnumError struct { Target string Current interface{} Enums []interface{} }
Example ¶
fmt.Println(&NotInEnumError{ Target: "int value", Current: "11", Enums: []interface{}{ "1", "2", "3", }, })
Output: int value should be one of 1, 2, 3, but got invalid value 11
func (*NotInEnumError) Error ¶
func (e *NotInEnumError) Error() string
type NotMatchError ¶
Example ¶
fmt.Println(&NotMatchError{ Target: "number", Current: "1", Pattern: `/\d+/`, })
Output: number /\d+/ not match 1
func (*NotMatchError) Error ¶
func (err *NotMatchError) Error() string
type OutOfRangeError ¶
type OutOfRangeError struct { Target string Current interface{} Minimum interface{} Maximum interface{} ExclusiveMaximum bool ExclusiveMinimum bool }
Example ¶
fmt.Println(&OutOfRangeError{ Target: "int value", Minimum: "1", Maximum: "10", Current: "11", ExclusiveMinimum: true, ExclusiveMaximum: true, })
Output: int value should be larger or equal than 1 and less or equal than 10, but got invalid value 11
func (*OutOfRangeError) Error ¶
func (e *OutOfRangeError) Error() string
type PreprocessStage ¶
type PreprocessStage int
const ( PreprocessSkip PreprocessStage = iota PreprocessString PreprocessPtr )
type Rule ¶
func ParseRuleWithType ¶
func (*Rule) SetDefaultValue ¶
func (*Rule) SetOptional ¶
type RuleModifier ¶
type RuleProcessor ¶
type RuleProcessor = func(rule RuleModifier)
type SliceValidator ¶
Validator for slice
Rules:
@slice<ELEM_RULE>[minLen,maxLen] @slice<ELEM_RULE>[length] @slice<@string{A,B,C}>[,100]
Aliases
@array = @slice // and range must to be use length
func (SliceValidator) Names ¶
func (SliceValidator) Names() []string
func (*SliceValidator) String ¶
func (validator *SliceValidator) String() string
func (*SliceValidator) Validate ¶
func (validator *SliceValidator) Validate(v interface{}) error
func (*SliceValidator) ValidateReflectValue ¶
func (validator *SliceValidator) ValidateReflectValue(rv reflect.Value) error
type StrLenMode ¶
type StrLenMode string
const ( StrLenModeLength StrLenMode = "length" StrLenModeRuneCount StrLenMode = "rune_count" )
type StrfmtValidator ¶
type StrfmtValidator struct {
// contains filtered or unexported fields
}
func NewRegexpStrfmtValidator ¶
func NewRegexpStrfmtValidator(regexpStr string, name string, aliases ...string) *StrfmtValidator
Example ¶
AlphaValidator := NewRegexpStrfmtValidator("^[a-zA-Z]+$", "alpha") fmt.Println(AlphaValidator.Validate("a")) fmt.Println(AlphaValidator.Validate("1"))
Output: <nil> alpha ^[a-zA-Z]+$ not match 1
func NewStrfmtValidator ¶
func NewStrfmtValidator(validate func(v interface{}) error, name string, aliases ...string) *StrfmtValidator
func (*StrfmtValidator) Names ¶
func (validator *StrfmtValidator) Names() []string
func (*StrfmtValidator) String ¶
func (validator *StrfmtValidator) String() string
func (*StrfmtValidator) TypeCheck ¶
func (validator *StrfmtValidator) TypeCheck(rule *Rule) error
func (*StrfmtValidator) Validate ¶
func (validator *StrfmtValidator) Validate(v interface{}) error
type StringValidator ¶
type StringValidator struct { Pattern string LenMode StrLenMode MinLength uint64 MaxLength *uint64 Enums []string }
Validator for string
Rules:
@string/regexp/ @string{VALUE_1,VALUE_2,VALUE_3} @string<StrLenMode>[from,to] @string<StrLenMode>[length]
ranges
@string[min,max] @string[length] @string[1,10] // string length should large or equal than 1 and less or equal than 10 @string[1,] // string length should large or equal than 1 and less than the maxinum of int32 @string[,1] // string length should less than 1 and large or equal than 0 @string[10] // string length should be equal 10
enumeration
@string{A,B,C} // should one of these values
regexp
@string/\w+/ // string values should match \w+
since we use / as wrapper for regexp, we need to use \ to escape /
length mode in parameter
@string<length> // use string length directly @string<rune_count> // use rune count as string length
composes
@string<>[1,]
aliases:
@char = @string<rune_count>
func (StringValidator) Names ¶
func (StringValidator) Names() []string
func (*StringValidator) String ¶
func (validator *StringValidator) String() string
func (*StringValidator) TypeCheck ¶
func (validator *StringValidator) TypeCheck(rule *Rule) error
func (*StringValidator) Validate ¶
func (validator *StringValidator) Validate(v interface{}) error
type StructValidator ¶
type StructValidator struct {
// contains filtered or unexported fields
}
func NewStructValidator ¶
func NewStructValidator(namedTagKey string) *StructValidator
Example ¶
type Named string type SubPtrStruct struct { PtrInt *int `validate:"@int[1,]"` PtrFloat *float32 `validate:"@float[1,]"` PtrUint *uint `validate:"@uint[1,]"` } type SubStruct struct { Int int `json:"int" validate:"@int[1,]"` Float float32 `json:"float" validate:"@float[1,]"` Uint uint `json:"uint" validate:"@uint[1,]"` } type SomeStruct struct { JustRequired string CanEmpty *string `validate:"@string[0,]?"` String string `validate:"@string[1,]"` Named Named `validate:"@string[2,]"` PtrString *string `validate:"@string[3,]" default:"123"` SomeStringer *SomeTextMarshaler `validate:"@string[20,]"` Slice []string `validate:"@slice<@string[1,]>"` SliceStruct []SubStruct `validate:"@slice"` Map map[string]string `validate:"@map<@string[2,],@string[1,]>"` MapStruct map[string]SubStruct `validate:"@map<@string[2,],>"` Struct SubStruct SubStruct *SubPtrStruct } validator := NewStructValidator("json") ctx := ContextWithValidatorMgr(context.Background(), ValidatorMgrDefault) structValidator, err := validator.New(ContextWithValidatorMgr(ctx, ValidatorMgrDefault), &Rule{ Type: typesutil.FromRType(reflect.TypeOf(&SomeStruct{}).Elem()), }) if err != nil { return } s := SomeStruct{ Slice: []string{"", ""}, SliceStruct: []SubStruct{ {Int: 0}, }, Map: map[string]string{ "1": "", "11": "", "12": "", }, MapStruct: map[string]SubStruct{ "222": SubStruct{}, }, } errForValidate := structValidator.Validate(s) errSet := map[string]string{} errKeyPaths := make([]string, 0) errForValidate.(*ErrorSet).Flatten().Each(func(fieldErr *FieldError) { errSet[fieldErr.Path.String()] = strconv.Quote(fieldErr.Error.Error()) errKeyPaths = append(errKeyPaths, fieldErr.Path.String()) }) sort.Strings(errKeyPaths) for i := range errKeyPaths { k := errKeyPaths[i] fmt.Println(k, errSet[k]) }
Output: JustRequired "missing required field" Map.1 "missing required field" Map.1/key "string length should be larger than 2, but got invalid value 1" Map.11 "missing required field" Map.12 "missing required field" MapStruct.222.float "missing required field" MapStruct.222.int "missing required field" MapStruct.222.uint "missing required field" Named "missing required field" PtrFloat "missing required field" PtrInt "missing required field" PtrString "missing required field" PtrUint "missing required field" SliceStruct[0].float "missing required field" SliceStruct[0].int "missing required field" SliceStruct[0].uint "missing required field" Slice[0] "missing required field" Slice[1] "missing required field" SomeStringer "missing required field" String "missing required field" Struct.float "missing required field" Struct.int "missing required field" Struct.uint "missing required field" float "missing required field" int "missing required field" uint "missing required field"
func (StructValidator) Names ¶
func (StructValidator) Names() []string
func (*StructValidator) String ¶
func (validator *StructValidator) String() string
func (*StructValidator) Validate ¶
func (validator *StructValidator) Validate(v interface{}) error
func (*StructValidator) ValidateReflectValue ¶
func (validator *StructValidator) ValidateReflectValue(rv reflect.Value) error
type UintValidator ¶
type UintValidator struct { BitSize uint Minimum uint64 Maximum uint64 MultipleOf uint64 ExclusiveMaximum bool ExclusiveMinimum bool Enums []uint64 }
Validator for uint
ranges
@uint[min,max] @uint[1,10] // value should large or equal than 1 and less or equal than 10 @uint(1,10] // value should large than 1 and less or equal than 10 @uint[1,10) // value should large or equal than 1 @uint[1,) // value should large or equal than 1 and less than the maxinum of int32 @uint[,1) // value should less than 1 and large or equal than 0 @uint // value should less or equal than maxinum of int32 and large or equal than 0
enumeration
@uint{1,2,3} // should one of these values
multiple of some int value
@uint{%multipleOf} @uint{%2} // should be multiple of 2
bit size in parameter
@uint<8> @uint<16> @uint<32> @uint<64>
composes
@uint<8>[1,]
aliases:
@uint8 = @uint<8> @uint16 = @uint<16> @uint32 = @uint<32> @uint64 = @uint<64>
Tips: for JavaScript https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER
uint<53>
func (UintValidator) Names ¶
func (UintValidator) Names() []string
func (*UintValidator) SetDefaults ¶
func (validator *UintValidator) SetDefaults()
func (*UintValidator) String ¶
func (validator *UintValidator) String() string
func (*UintValidator) TypeCheck ¶
func (validator *UintValidator) TypeCheck(rule *Rule) error
func (*UintValidator) Validate ¶
func (validator *UintValidator) Validate(v interface{}) error
type UnsupportedTypeError ¶
type UnsupportedTypeError struct {
// contains filtered or unexported fields
}
func NewUnsupportedTypeError ¶
func NewUnsupportedTypeError(typ string, rule string, msgs ...string) *UnsupportedTypeError
func (*UnsupportedTypeError) Error ¶
func (e *UnsupportedTypeError) Error() string
type ValidatorCreator ¶
type ValidatorFactory ¶
type ValidatorFactory struct {
// contains filtered or unexported fields
}
func NewValidatorFactory ¶
func NewValidatorFactory() *ValidatorFactory
func (*ValidatorFactory) Compile ¶
func (f *ValidatorFactory) Compile(ctx context.Context, ruleBytes []byte, typ typesutil.Type, ruleProcessors ...RuleProcessor) (validator Validator, err error)
func (*ValidatorFactory) MustCompile ¶
func (f *ValidatorFactory) MustCompile(ctx context.Context, rule []byte, typ typesutil.Type, ruleProcessors ...RuleProcessor) Validator
func (*ValidatorFactory) Register ¶
func (f *ValidatorFactory) Register(validators ...ValidatorCreator)
type ValidatorLoader ¶
type ValidatorLoader struct { ValidatorCreator ValidatorCreator Validator PreprocessStage DefaultValue []byte Optional bool ErrMsg []byte }
func NewValidatorLoader ¶
func NewValidatorLoader(validatorCreator ValidatorCreator) *ValidatorLoader
func (*ValidatorLoader) String ¶
func (loader *ValidatorLoader) String() string
func (*ValidatorLoader) Validate ¶
func (loader *ValidatorLoader) Validate(v interface{}) error
type ValidatorMgr ¶
type ValidatorMgr interface { // Compile compile rule string to validator Compile(context.Context, []byte, typesutil.Type, ...RuleProcessor) (Validator, error) }
ValidatorMgr mgr for compiling validator
func ValidatorMgrFromContext ¶
func ValidatorMgrFromContext(c context.Context) ValidatorMgr