validate/rules.go

143 lines
3.9 KiB
Go

package validate
import (
"reflect"
"regexp"
"strings"
)
type listFunc func(reflect.Value, interface{}) bool
type listFuncInfo struct {
inputFunc func(reflect.Kind, string) interface{}
kinds _kinds
}
type _kinds map[reflect.Kind]listFunc
// 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)
},
}},
}