mirror of
https://github.com/astaxie/beego.git
synced 2024-11-25 18:50:55 +00:00
commit
a242f61b8e
177
validation/validation.go
Normal file
177
validation/validation.go
Normal file
@ -0,0 +1,177 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
type ValidationError struct {
|
||||
Message, Key string
|
||||
}
|
||||
|
||||
// Returns the Message.
|
||||
func (e *ValidationError) String() string {
|
||||
if e == nil {
|
||||
return ""
|
||||
}
|
||||
return e.Message
|
||||
}
|
||||
|
||||
// A Validation context manages data validation and error messages.
|
||||
type Validation struct {
|
||||
Errors []*ValidationError
|
||||
}
|
||||
|
||||
func (v *Validation) Clear() {
|
||||
v.Errors = []*ValidationError{}
|
||||
}
|
||||
|
||||
func (v *Validation) HasErrors() bool {
|
||||
return len(v.Errors) > 0
|
||||
}
|
||||
|
||||
// Return the errors mapped by key.
|
||||
// If there are multiple validation errors associated with a single key, the
|
||||
// first one "wins". (Typically the first validation will be the more basic).
|
||||
func (v *Validation) ErrorMap() map[string]*ValidationError {
|
||||
m := map[string]*ValidationError{}
|
||||
for _, e := range v.Errors {
|
||||
if _, ok := m[e.Key]; !ok {
|
||||
m[e.Key] = e
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// Add an error to the validation context.
|
||||
func (v *Validation) Error(message string, args ...interface{}) *ValidationResult {
|
||||
result := (&ValidationResult{
|
||||
Ok: false,
|
||||
Error: &ValidationError{},
|
||||
}).Message(message, args...)
|
||||
v.Errors = append(v.Errors, result.Error)
|
||||
return result
|
||||
}
|
||||
|
||||
// A ValidationResult is returned from every validation method.
|
||||
// It provides an indication of success, and a pointer to the Error (if any).
|
||||
type ValidationResult struct {
|
||||
Error *ValidationError
|
||||
Ok bool
|
||||
}
|
||||
|
||||
func (r *ValidationResult) Key(key string) *ValidationResult {
|
||||
if r.Error != nil {
|
||||
r.Error.Key = key
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *ValidationResult) Message(message string, args ...interface{}) *ValidationResult {
|
||||
if r.Error != nil {
|
||||
if len(args) == 0 {
|
||||
r.Error.Message = message
|
||||
} else {
|
||||
r.Error.Message = fmt.Sprintf(message, args...)
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// Test that the argument is non-nil and non-empty (if string or list)
|
||||
func (v *Validation) Required(obj interface{}, key string) *ValidationResult {
|
||||
return v.apply(Required{key}, obj)
|
||||
}
|
||||
|
||||
func (v *Validation) Min(n int, min int, key string) *ValidationResult {
|
||||
return v.apply(Min{min, key}, n)
|
||||
}
|
||||
|
||||
func (v *Validation) Max(n int, max int, key string) *ValidationResult {
|
||||
return v.apply(Max{max, key}, n)
|
||||
}
|
||||
|
||||
func (v *Validation) Range(n, min, max int, key string) *ValidationResult {
|
||||
return v.apply(Range{Min{Min: min}, Max{Max: max}, key}, n)
|
||||
}
|
||||
|
||||
func (v *Validation) MinSize(obj interface{}, min int, key string) *ValidationResult {
|
||||
return v.apply(MinSize{min, key}, obj)
|
||||
}
|
||||
|
||||
func (v *Validation) MaxSize(obj interface{}, max int, key string) *ValidationResult {
|
||||
return v.apply(MaxSize{max, key}, obj)
|
||||
}
|
||||
|
||||
func (v *Validation) Length(obj interface{}, n int, key string) *ValidationResult {
|
||||
return v.apply(Length{n, key}, obj)
|
||||
}
|
||||
|
||||
func (v *Validation) Alpha(obj interface{}, key string) *ValidationResult {
|
||||
return v.apply(Alpha{key}, obj)
|
||||
}
|
||||
|
||||
func (v *Validation) Numeric(obj interface{}, key string) *ValidationResult {
|
||||
return v.apply(Numeric{key}, obj)
|
||||
}
|
||||
|
||||
func (v *Validation) AlphaNumeric(obj interface{}, key string) *ValidationResult {
|
||||
return v.apply(AlphaNumeric{key}, obj)
|
||||
}
|
||||
|
||||
func (v *Validation) Match(str string, regex *regexp.Regexp, key string) *ValidationResult {
|
||||
return v.apply(Match{regex, key}, str)
|
||||
}
|
||||
|
||||
func (v *Validation) NoMatch(str string, regex *regexp.Regexp, key string) *ValidationResult {
|
||||
return v.apply(NoMatch{Match{Regexp: regex}, key}, str)
|
||||
}
|
||||
|
||||
func (v *Validation) AlphaDash(str string, key string) *ValidationResult {
|
||||
return v.apply(AlphaDash{NoMatch{Match: Match{Regexp: alphaDashPattern}}, key}, str)
|
||||
}
|
||||
|
||||
func (v *Validation) Email(str string, key string) *ValidationResult {
|
||||
return v.apply(Email{Match{Regexp: emailPattern}, key}, str)
|
||||
}
|
||||
|
||||
func (v *Validation) IP(str string, key string) *ValidationResult {
|
||||
return v.apply(IP{Match{Regexp: ipPattern}, key}, str)
|
||||
}
|
||||
|
||||
func (v *Validation) Base64(str string, key string) *ValidationResult {
|
||||
return v.apply(Base64{Match{Regexp: base64Pattern}, key}, str)
|
||||
}
|
||||
|
||||
func (v *Validation) apply(chk Validator, obj interface{}) *ValidationResult {
|
||||
if chk.IsSatisfied(obj) {
|
||||
return &ValidationResult{Ok: true}
|
||||
}
|
||||
|
||||
// Add the error to the validation context.
|
||||
err := &ValidationError{
|
||||
Message: chk.DefaultMessage(),
|
||||
Key: chk.GetKey(),
|
||||
}
|
||||
v.Errors = append(v.Errors, err)
|
||||
|
||||
// Also return it in the result.
|
||||
return &ValidationResult{
|
||||
Ok: false,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
||||
// Apply a group of validators to a field, in order, and return the
|
||||
// ValidationResult from the first one that fails, or the last one that
|
||||
// succeeds.
|
||||
func (v *Validation) Check(obj interface{}, checks ...Validator) *ValidationResult {
|
||||
var result *ValidationResult
|
||||
for _, check := range checks {
|
||||
result = v.apply(check, obj)
|
||||
if !result.Ok {
|
||||
return result
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
219
validation/validation_test.go
Normal file
219
validation/validation_test.go
Normal file
@ -0,0 +1,219 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestRequired(t *testing.T) {
|
||||
valid := Validation{}
|
||||
|
||||
if valid.Required(nil, "nil").Ok {
|
||||
t.Error("nil object should be false")
|
||||
}
|
||||
if valid.Required("", "string").Ok {
|
||||
t.Error("\"'\" string should be false")
|
||||
}
|
||||
if !valid.Required("astaxie", "string").Ok {
|
||||
t.Error("string should be true")
|
||||
}
|
||||
if valid.Required(0, "zero").Ok {
|
||||
t.Error("Integer should not be equal 0")
|
||||
}
|
||||
if !valid.Required(1, "int").Ok {
|
||||
t.Error("Integer except 0 should be true")
|
||||
}
|
||||
if !valid.Required(time.Now(), "time").Ok {
|
||||
t.Error("time should be true")
|
||||
}
|
||||
if valid.Required([]string{}, "emptySlice").Ok {
|
||||
t.Error("empty slice should be false")
|
||||
}
|
||||
if !valid.Required([]interface{}{"ok"}, "slice").Ok {
|
||||
t.Error("slice should be equal true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMin(t *testing.T) {
|
||||
valid := Validation{}
|
||||
|
||||
if valid.Min(-1, 0, "min0").Ok {
|
||||
t.Error("-1 is less than the minimum value of 0 should be false")
|
||||
}
|
||||
if !valid.Min(1, 0, "min0").Ok {
|
||||
t.Error("1 is greater or equal than the minimum value of 0 should be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMax(t *testing.T) {
|
||||
valid := Validation{}
|
||||
|
||||
if valid.Max(1, 0, "max0").Ok {
|
||||
t.Error("1 is greater than the minimum value of 0 should be false")
|
||||
}
|
||||
if !valid.Max(-1, 0, "max0").Ok {
|
||||
t.Error("-1 is less or equal than the maximum value of 0 should be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRange(t *testing.T) {
|
||||
valid := Validation{}
|
||||
|
||||
if valid.Range(-1, 0, 1, "range0_1").Ok {
|
||||
t.Error("-1 is bettween 0 and 1 should be false")
|
||||
}
|
||||
if !valid.Range(1, 0, 1, "range0_1").Ok {
|
||||
t.Error("1 is bettween 0 and 1 should be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMinSize(t *testing.T) {
|
||||
valid := Validation{}
|
||||
|
||||
if valid.MinSize("", 1, "minSize1").Ok {
|
||||
t.Error("the length of \"\" is less than the minimum value of 1 should be false")
|
||||
}
|
||||
if !valid.MinSize("ok", 1, "minSize1").Ok {
|
||||
t.Error("the length of \"ok\" is greater or equal than the minimum value of 1 should be true")
|
||||
}
|
||||
if valid.MinSize([]string{}, 1, "minSize1").Ok {
|
||||
t.Error("the length of empty slice is less than the minimum value of 1 should be false")
|
||||
}
|
||||
if !valid.MinSize([]interface{}{"ok"}, 1, "minSize1").Ok {
|
||||
t.Error("the length of [\"ok\"] is greater or equal than the minimum value of 1 should be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMaxSize(t *testing.T) {
|
||||
valid := Validation{}
|
||||
|
||||
if valid.MaxSize("ok", 1, "maxSize1").Ok {
|
||||
t.Error("the length of \"ok\" is greater than the maximum value of 1 should be false")
|
||||
}
|
||||
if !valid.MaxSize("", 1, "maxSize1").Ok {
|
||||
t.Error("the length of \"\" is less or equal than the maximum value of 1 should be true")
|
||||
}
|
||||
if valid.MaxSize([]interface{}{"ok", false}, 1, "maxSize1").Ok {
|
||||
t.Error("the length of [\"ok\", false] is greater than the maximum value of 1 should be false")
|
||||
}
|
||||
if !valid.MaxSize([]string{}, 1, "maxSize1").Ok {
|
||||
t.Error("the length of empty slice is less or equal than the maximum value of 1 should be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLength(t *testing.T) {
|
||||
valid := Validation{}
|
||||
|
||||
if valid.Length("", 1, "length1").Ok {
|
||||
t.Error("the length of \"\" must equal 1 should be false")
|
||||
}
|
||||
if !valid.Length("1", 1, "length1").Ok {
|
||||
t.Error("the length of \"1\" must equal 1 should be true")
|
||||
}
|
||||
if valid.Length([]string{}, 1, "length1").Ok {
|
||||
t.Error("the length of empty slice must equal 1 should be false")
|
||||
}
|
||||
if !valid.Length([]interface{}{"ok"}, 1, "length1").Ok {
|
||||
t.Error("the length of [\"ok\"] must equal 1 should be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAlpha(t *testing.T) {
|
||||
valid := Validation{}
|
||||
|
||||
if valid.Alpha("a,1-@ $", "alpha").Ok {
|
||||
t.Error("\"a,1-@ $\" are valid alpha characters should be false")
|
||||
}
|
||||
if !valid.Alpha("abCD", "alpha").Ok {
|
||||
t.Error("\"abCD\" are valid alpha characters should be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNumeric(t *testing.T) {
|
||||
valid := Validation{}
|
||||
|
||||
if valid.Numeric("a,1-@ $", "numeric").Ok {
|
||||
t.Error("\"a,1-@ $\" are valid numeric characters should be false")
|
||||
}
|
||||
if !valid.Numeric("1234", "numeric").Ok {
|
||||
t.Error("\"1234\" are valid numeric characters should be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAlphaNumeric(t *testing.T) {
|
||||
valid := Validation{}
|
||||
|
||||
if valid.AlphaNumeric("a,1-@ $", "alphaNumeric").Ok {
|
||||
t.Error("\"a,1-@ $\" are valid alpha or numeric characters should be false")
|
||||
}
|
||||
if !valid.AlphaNumeric("1234aB", "alphaNumeric").Ok {
|
||||
t.Error("\"1234aB\" are valid alpha or numeric characters should be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatch(t *testing.T) {
|
||||
valid := Validation{}
|
||||
|
||||
if valid.Match("suchuangji@gmail", regexp.MustCompile("^\\w+@\\w+\\.\\w+$"), "match").Ok {
|
||||
t.Error("\"suchuangji@gmail\" match \"^\\w+@\\w+\\.\\w+$\" should be false")
|
||||
}
|
||||
if !valid.Match("suchuangji@gmail.com", regexp.MustCompile("^\\w+@\\w+\\.\\w+$"), "match").Ok {
|
||||
t.Error("\"suchuangji@gmail\" match \"^\\w+@\\w+\\.\\w+$\" should be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoMatch(t *testing.T) {
|
||||
valid := Validation{}
|
||||
|
||||
if valid.NoMatch("123@gmail", regexp.MustCompile("[^\\w\\d]"), "nomatch").Ok {
|
||||
t.Error("\"123@gmail\" not match \"[^\\w\\d]\" should be false")
|
||||
}
|
||||
if !valid.NoMatch("123gmail", regexp.MustCompile("[^\\w\\d]"), "match").Ok {
|
||||
t.Error("\"123@gmail\" not match \"[^\\w\\d@]\" should be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAlphaDash(t *testing.T) {
|
||||
valid := Validation{}
|
||||
|
||||
if valid.AlphaDash("a,1-@ $", "alphaDash").Ok {
|
||||
t.Error("\"a,1-@ $\" are valid alpha or numeric or dash(-_) characters should be false")
|
||||
}
|
||||
if !valid.AlphaDash("1234aB-_", "alphaDash").Ok {
|
||||
t.Error("\"1234aB\" are valid alpha or numeric or dash(-_) characters should be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmail(t *testing.T) {
|
||||
valid := Validation{}
|
||||
|
||||
if valid.Email("not@a email", "email").Ok {
|
||||
t.Error("\"not@a email\" is a valid email address should be false")
|
||||
}
|
||||
if !valid.Email("suchuangji@gmail.com", "email").Ok {
|
||||
t.Error("\"suchuangji@gmail.com\" is a valid email address should be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIP(t *testing.T) {
|
||||
valid := Validation{}
|
||||
|
||||
if valid.IP("11.255.255.256", "IP").Ok {
|
||||
t.Error("\"11.255.255.256\" is a valid ip address should be false")
|
||||
}
|
||||
if !valid.IP("01.11.11.11", "IP").Ok {
|
||||
t.Error("\"suchuangji@gmail.com\" is a valid ip address should be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBase64(t *testing.T) {
|
||||
valid := Validation{}
|
||||
|
||||
if valid.Base64("suchuangji@gmail.com", "base64").Ok {
|
||||
t.Error("\"suchuangji@gmail.com\" are a valid base64 characters should be false")
|
||||
}
|
||||
if !valid.Base64("c3VjaHVhbmdqaUBnbWFpbC5jb20=", "base64").Ok {
|
||||
t.Error("\"c3VjaHVhbmdqaUBnbWFpbC5jb20=\" are a valid base64 characters should be true")
|
||||
}
|
||||
}
|
355
validation/validators.go
Normal file
355
validation/validators.go
Normal file
@ -0,0 +1,355 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Validator interface {
|
||||
IsSatisfied(interface{}) bool
|
||||
DefaultMessage() string
|
||||
GetKey() string
|
||||
}
|
||||
|
||||
type Required struct {
|
||||
Key string
|
||||
}
|
||||
|
||||
func (r Required) IsSatisfied(obj interface{}) bool {
|
||||
if obj == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if str, ok := obj.(string); ok {
|
||||
return len(str) > 0
|
||||
}
|
||||
if b, ok := obj.(bool); ok {
|
||||
return b
|
||||
}
|
||||
if i, ok := obj.(int); ok {
|
||||
return i != 0
|
||||
}
|
||||
if t, ok := obj.(time.Time); ok {
|
||||
return !t.IsZero()
|
||||
}
|
||||
v := reflect.ValueOf(obj)
|
||||
if v.Kind() == reflect.Slice {
|
||||
return v.Len() > 0
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (r Required) DefaultMessage() string {
|
||||
return "Required"
|
||||
}
|
||||
|
||||
func (r Required) GetKey() string {
|
||||
return r.Key
|
||||
}
|
||||
|
||||
type Min struct {
|
||||
Min int
|
||||
Key string
|
||||
}
|
||||
|
||||
func (m Min) IsSatisfied(obj interface{}) bool {
|
||||
num, ok := obj.(int)
|
||||
if ok {
|
||||
return num >= m.Min
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m Min) DefaultMessage() string {
|
||||
return fmt.Sprintln("Minimum is", m.Min)
|
||||
}
|
||||
|
||||
func (m Min) GetKey() string {
|
||||
return m.Key
|
||||
}
|
||||
|
||||
type Max struct {
|
||||
Max int
|
||||
Key string
|
||||
}
|
||||
|
||||
func (m Max) IsSatisfied(obj interface{}) bool {
|
||||
num, ok := obj.(int)
|
||||
if ok {
|
||||
return num <= m.Max
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m Max) DefaultMessage() string {
|
||||
return fmt.Sprintln("Maximum is", m.Max)
|
||||
}
|
||||
|
||||
func (m Max) GetKey() string {
|
||||
return m.Key
|
||||
}
|
||||
|
||||
// Requires an integer to be within Min, Max inclusive.
|
||||
type Range struct {
|
||||
Min
|
||||
Max
|
||||
Key string
|
||||
}
|
||||
|
||||
func (r Range) IsSatisfied(obj interface{}) bool {
|
||||
return r.Min.IsSatisfied(obj) && r.Max.IsSatisfied(obj)
|
||||
}
|
||||
|
||||
func (r Range) DefaultMessage() string {
|
||||
return fmt.Sprintln("Range is", r.Min.Min, "to", r.Max.Max)
|
||||
}
|
||||
|
||||
func (r Range) GetKey() string {
|
||||
return r.Key
|
||||
}
|
||||
|
||||
// Requires an array or string to be at least a given length.
|
||||
type MinSize struct {
|
||||
Min int
|
||||
Key string
|
||||
}
|
||||
|
||||
func (m MinSize) IsSatisfied(obj interface{}) bool {
|
||||
if str, ok := obj.(string); ok {
|
||||
return len(str) >= m.Min
|
||||
}
|
||||
v := reflect.ValueOf(obj)
|
||||
if v.Kind() == reflect.Slice {
|
||||
return v.Len() >= m.Min
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m MinSize) DefaultMessage() string {
|
||||
return fmt.Sprintln("Minimum size is", m.Min)
|
||||
}
|
||||
|
||||
func (m MinSize) GetKey() string {
|
||||
return m.Key
|
||||
}
|
||||
|
||||
// Requires an array or string to be at most a given length.
|
||||
type MaxSize struct {
|
||||
Max int
|
||||
Key string
|
||||
}
|
||||
|
||||
func (m MaxSize) IsSatisfied(obj interface{}) bool {
|
||||
if str, ok := obj.(string); ok {
|
||||
return len(str) <= m.Max
|
||||
}
|
||||
v := reflect.ValueOf(obj)
|
||||
if v.Kind() == reflect.Slice {
|
||||
return v.Len() <= m.Max
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m MaxSize) DefaultMessage() string {
|
||||
return fmt.Sprintln("Maximum size is", m.Max)
|
||||
}
|
||||
|
||||
func (m MaxSize) GetKey() string {
|
||||
return m.Key
|
||||
}
|
||||
|
||||
// Requires an array or string to be exactly a given length.
|
||||
type Length struct {
|
||||
N int
|
||||
Key string
|
||||
}
|
||||
|
||||
func (l Length) IsSatisfied(obj interface{}) bool {
|
||||
if str, ok := obj.(string); ok {
|
||||
return len(str) == l.N
|
||||
}
|
||||
v := reflect.ValueOf(obj)
|
||||
if v.Kind() == reflect.Slice {
|
||||
return v.Len() == l.N
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (l Length) DefaultMessage() string {
|
||||
return fmt.Sprintln("Required length is", l.N)
|
||||
}
|
||||
|
||||
func (l Length) GetKey() string {
|
||||
return l.Key
|
||||
}
|
||||
|
||||
type Alpha struct {
|
||||
Key string
|
||||
}
|
||||
|
||||
func (a Alpha) IsSatisfied(obj interface{}) bool {
|
||||
if str, ok := obj.(string); ok {
|
||||
for _, v := range str {
|
||||
if ('Z' < v || v < 'A') && ('z' < v || v < 'a') {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (a Alpha) DefaultMessage() string {
|
||||
return fmt.Sprintln("Must be valid alpha characters")
|
||||
}
|
||||
|
||||
func (a Alpha) GetKey() string {
|
||||
return a.Key
|
||||
}
|
||||
|
||||
type Numeric struct {
|
||||
Key string
|
||||
}
|
||||
|
||||
func (n Numeric) IsSatisfied(obj interface{}) bool {
|
||||
if str, ok := obj.(string); ok {
|
||||
for _, v := range str {
|
||||
if '9' < v || v < '0' {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (n Numeric) DefaultMessage() string {
|
||||
return fmt.Sprintln("Must be valid numeric characters")
|
||||
}
|
||||
|
||||
func (n Numeric) GetKey() string {
|
||||
return n.Key
|
||||
}
|
||||
|
||||
type AlphaNumeric struct {
|
||||
Key string
|
||||
}
|
||||
|
||||
func (a AlphaNumeric) IsSatisfied(obj interface{}) bool {
|
||||
if str, ok := obj.(string); ok {
|
||||
for _, v := range str {
|
||||
if ('Z' < v || v < 'A') && ('z' < v || v < 'a') && ('9' < v || v < '0') {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (a AlphaNumeric) DefaultMessage() string {
|
||||
return fmt.Sprintln("Must be valid alpha or numeric characters")
|
||||
}
|
||||
|
||||
func (a AlphaNumeric) GetKey() string {
|
||||
return a.Key
|
||||
}
|
||||
|
||||
// Requires a string to match a given regex.
|
||||
type Match struct {
|
||||
Regexp *regexp.Regexp
|
||||
Key string
|
||||
}
|
||||
|
||||
func (m Match) IsSatisfied(obj interface{}) bool {
|
||||
str := obj.(string)
|
||||
return m.Regexp.MatchString(str)
|
||||
}
|
||||
|
||||
func (m Match) DefaultMessage() string {
|
||||
return fmt.Sprintln("Must match", m.Regexp)
|
||||
}
|
||||
|
||||
func (m Match) GetKey() string {
|
||||
return m.Key
|
||||
}
|
||||
|
||||
// Requires a string to not match a given regex.
|
||||
type NoMatch struct {
|
||||
Match
|
||||
Key string
|
||||
}
|
||||
|
||||
func (n NoMatch) IsSatisfied(obj interface{}) bool {
|
||||
return !n.Match.IsSatisfied(obj)
|
||||
}
|
||||
|
||||
func (n NoMatch) DefaultMessage() string {
|
||||
return fmt.Sprintln("Must not match", n.Regexp)
|
||||
}
|
||||
|
||||
func (n NoMatch) GetKey() string {
|
||||
return n.Key
|
||||
}
|
||||
|
||||
var alphaDashPattern = regexp.MustCompile("[^\\d\\w-_]")
|
||||
|
||||
type AlphaDash struct {
|
||||
NoMatch
|
||||
Key string
|
||||
}
|
||||
|
||||
func (a AlphaDash) DefaultMessage() string {
|
||||
return fmt.Sprintln("Must be valid alpha or numeric or dash(-_) characters")
|
||||
}
|
||||
|
||||
func (a AlphaDash) GetKey() string {
|
||||
return a.Key
|
||||
}
|
||||
|
||||
var emailPattern = regexp.MustCompile("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?")
|
||||
|
||||
type Email struct {
|
||||
Match
|
||||
Key string
|
||||
}
|
||||
|
||||
func (e Email) DefaultMessage() string {
|
||||
return fmt.Sprintln("Must be a valid email address")
|
||||
}
|
||||
|
||||
func (e Email) GetKey() string {
|
||||
return e.Key
|
||||
}
|
||||
|
||||
var ipPattern = regexp.MustCompile("^((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)$")
|
||||
|
||||
type IP struct {
|
||||
Match
|
||||
Key string
|
||||
}
|
||||
|
||||
func (i IP) DefaultMessage() string {
|
||||
return fmt.Sprintln("Must be a valid ip address")
|
||||
}
|
||||
|
||||
func (i IP) GetKey() string {
|
||||
return i.Key
|
||||
}
|
||||
|
||||
var base64Pattern = regexp.MustCompile("^(?:[A-Za-z0-99+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$")
|
||||
|
||||
type Base64 struct {
|
||||
Match
|
||||
Key string
|
||||
}
|
||||
|
||||
func (b Base64) DefaultMessage() string {
|
||||
return fmt.Sprintln("Must be valid base64 characters")
|
||||
}
|
||||
|
||||
func (b Base64) GetKey() string {
|
||||
return b.Key
|
||||
}
|
Loading…
Reference in New Issue
Block a user