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 `gte`: {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) }, }}, `lte`: {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) }, }}, `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) }, }}, }