You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
4.8 KiB
172 lines
4.8 KiB
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) |
|
}, |
|
}}, |
|
}
|
|
|