forked from Fuyu/validate
151 lines
4.1 KiB
Go
151 lines
4.1 KiB
Go
package validate
|
|
|
|
import (
|
|
"reflect"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
// ValidationFunc is a function to validate a field
|
|
type ValidationFunc func(reflect.Value, interface{}) bool
|
|
|
|
// Kinds is a map with validation funcs for each reflect.Kind
|
|
type Kinds map[reflect.Kind]ValidationFunc
|
|
|
|
type listFuncInfo struct {
|
|
inputFunc InputFunc
|
|
kinds Kinds
|
|
}
|
|
|
|
// AddRule adds a rule to the list of validation functions
|
|
func AddRule(name string, inputFunc InputFunc, kinds Kinds) {
|
|
funcs[name] = listFuncInfo{inputFunc, kinds}
|
|
}
|
|
|
|
// nolint: dupl
|
|
var funcs = map[string]listFuncInfo{
|
|
`required`: {nil, Kinds{
|
|
reflect.Ptr: func(rv reflect.Value, _ interface{}) bool {
|
|
return !rv.IsNil()
|
|
},
|
|
reflect.Interface: func(rv reflect.Value, _ interface{}) bool {
|
|
return !rv.IsNil()
|
|
},
|
|
reflect.Slice: func(rv reflect.Value, _ interface{}) bool {
|
|
return !rv.IsNil() && rv.Len() > 0
|
|
},
|
|
reflect.Map: func(rv reflect.Value, _ interface{}) bool {
|
|
return !rv.IsNil() && rv.Len() > 0
|
|
},
|
|
reflect.String: func(rv reflect.Value, _ interface{}) bool {
|
|
return rv.String() != ``
|
|
},
|
|
reflect.Int: func(rv reflect.Value, _ interface{}) bool {
|
|
return rv.Int() != 0
|
|
},
|
|
reflect.Uint: func(rv reflect.Value, _ interface{}) bool {
|
|
return rv.Uint() != 0
|
|
},
|
|
reflect.Float64: func(rv reflect.Value, _ interface{}) bool {
|
|
return rv.Float() != 0
|
|
},
|
|
}},
|
|
|
|
// Strings
|
|
`prefix`: {InputSame, Kinds{
|
|
reflect.String: func(rv reflect.Value, val interface{}) bool {
|
|
return strings.HasPrefix(rv.String(), val.(string))
|
|
},
|
|
}},
|
|
`suffix`: {InputSame, Kinds{
|
|
reflect.String: func(rv reflect.Value, val interface{}) bool {
|
|
return strings.HasSuffix(rv.String(), val.(string))
|
|
},
|
|
}},
|
|
`contains`: {InputSame, Kinds{
|
|
reflect.String: func(rv reflect.Value, val interface{}) bool {
|
|
return strings.Contains(rv.String(), val.(string))
|
|
},
|
|
}},
|
|
`regexp`: {InputRegexp, Kinds{
|
|
reflect.String: func(rv reflect.Value, val interface{}) bool {
|
|
return val.(*regexp.Regexp).MatchString(rv.String())
|
|
},
|
|
}},
|
|
|
|
// Comparisons
|
|
`eq`: {InputSame, Kinds{
|
|
reflect.String: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.String() == val.(string)
|
|
},
|
|
reflect.Int: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.Int() == val.(int64)
|
|
},
|
|
reflect.Uint: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.Uint() == val.(uint64)
|
|
},
|
|
reflect.Float64: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.Float() == val.(float64)
|
|
},
|
|
}},
|
|
|
|
// Integers
|
|
`gt`: {InputSame, Kinds{
|
|
reflect.Int: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.Int() > val.(int64)
|
|
},
|
|
reflect.Uint: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.Uint() > val.(uint64)
|
|
},
|
|
reflect.Float64: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.Float() > val.(float64)
|
|
},
|
|
}},
|
|
`lt`: {InputSame, Kinds{
|
|
reflect.Int: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.Int() < val.(int64)
|
|
},
|
|
reflect.Uint: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.Uint() < val.(uint64)
|
|
},
|
|
reflect.Float64: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.Float() < val.(float64)
|
|
},
|
|
}},
|
|
|
|
// Slices, maps & strings
|
|
`len`: {InputInt, Kinds{
|
|
reflect.Slice: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.Len() == val.(int)
|
|
},
|
|
reflect.Map: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.Len() == val.(int)
|
|
},
|
|
reflect.String: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.Len() == val.(int)
|
|
},
|
|
}},
|
|
`min`: {InputInt, Kinds{
|
|
reflect.Slice: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.Len() >= val.(int)
|
|
},
|
|
reflect.Map: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.Len() >= val.(int)
|
|
},
|
|
reflect.String: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.Len() >= val.(int)
|
|
},
|
|
}},
|
|
`max`: {InputInt, Kinds{
|
|
reflect.Slice: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.Len() <= val.(int)
|
|
},
|
|
reflect.Map: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.Len() <= val.(int)
|
|
},
|
|
reflect.String: func(rv reflect.Value, val interface{}) bool {
|
|
return rv.Len() <= val.(int)
|
|
},
|
|
}},
|
|
}
|