From 2389bc72f9156b70c81958c87a1815096dd8dce5 Mon Sep 17 00:00:00 2001 From: astaxie Date: Sun, 13 Sep 2015 00:13:19 +0800 Subject: [PATCH] golint validation --- validation/util.go | 11 +- validation/util_test.go | 4 +- validation/validation.go | 192 +++++++++++++++++----------------- validation/validation_test.go | 6 +- validation/validators.go | 102 ++++++++++++++++-- 5 files changed, 202 insertions(+), 113 deletions(-) diff --git a/validation/util.go b/validation/util.go index 367da5dc..9e4f642d 100644 --- a/validation/util.go +++ b/validation/util.go @@ -23,7 +23,8 @@ import ( ) const ( - VALIDTAG = "valid" + // ValidTag struct tag + ValidTag = "valid" ) var ( @@ -55,16 +56,16 @@ func init() { } } -// Valid function type +// ValidFunc Valid function type type ValidFunc struct { Name string Params []interface{} } -// Validate function map +// Funcs Validate function map type Funcs map[string]reflect.Value -// validate values with named type string +// Call validate values with named type string func (f Funcs) Call(name string, params ...interface{}) (result []reflect.Value, err error) { defer func() { if r := recover(); r != nil { @@ -96,7 +97,7 @@ func isStructPtr(t reflect.Type) bool { } func getValidFuncs(f reflect.StructField) (vfs []ValidFunc, err error) { - tag := f.Tag.Get(VALIDTAG) + tag := f.Tag.Get(ValidTag) if len(tag) == 0 { return } diff --git a/validation/util_test.go b/validation/util_test.go index c4283c4e..d7e10506 100644 --- a/validation/util_test.go +++ b/validation/util_test.go @@ -20,7 +20,7 @@ import ( ) type user struct { - Id int + ID int Tag string `valid:"Maxx(aa)"` Name string `valid:"Required;"` Age int `valid:"Required;Range(1, 140)"` @@ -33,7 +33,7 @@ func TestGetValidFuncs(t *testing.T) { var vfs []ValidFunc var err error - f, _ := tf.FieldByName("Id") + f, _ := tf.FieldByName("ID") if vfs, err = getValidFuncs(f); err != nil { t.Fatal(err) } diff --git a/validation/validation.go b/validation/validation.go index d98ff190..76683d91 100644 --- a/validation/validation.go +++ b/validation/validation.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// package for validations +// Package validation for validations // // import ( // "github.com/astaxie/beego/validation" @@ -53,41 +53,43 @@ import ( "strings" ) +// ValidFormer valid interface type ValidFormer interface { Valid(*Validation) } -type ValidationError struct { +// Error show the error +type Error struct { Message, Key, Name, Field, Tmpl string Value interface{} LimitValue interface{} } -// Returns the Message. -func (e *ValidationError) String() string { +// String Returns the Message. +func (e *Error) String() string { if e == nil { return "" } return e.Message } -// A ValidationResult is returned from every validation method. +// Result 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 +type Result struct { + Error *Error Ok bool } -// Get ValidationResult by given key string. -func (r *ValidationResult) Key(key string) *ValidationResult { +// Key Get Result by given key string. +func (r *Result) Key(key string) *Result { if r.Error != nil { r.Error.Key = key } return r } -// Set ValidationResult message by string or format string with args -func (r *ValidationResult) Message(message string, args ...interface{}) *ValidationResult { +// Message Set Result message by string or format string with args +func (r *Result) Message(message string, args ...interface{}) *Result { if r.Error != nil { if len(args) == 0 { r.Error.Message = message @@ -100,142 +102,142 @@ func (r *ValidationResult) Message(message string, args ...interface{}) *Validat // A Validation context manages data validation and error messages. type Validation struct { - Errors []*ValidationError - ErrorsMap map[string]*ValidationError + Errors []*Error + ErrorsMap map[string]*Error } -// Clean all ValidationError. +// Clear Clean all ValidationError. func (v *Validation) Clear() { - v.Errors = []*ValidationError{} - v.ErrorsMap = nil + v.Errors = []*Error{} + v.ErrorsMap = nil } -// Has ValidationError nor not. +// HasErrors Has ValidationError nor not. func (v *Validation) HasErrors() bool { return len(v.Errors) > 0 } -// Return the errors mapped by key. +// ErrorMap 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 { +func (v *Validation) ErrorMap() map[string]*Error { return v.ErrorsMap } -// Add an error to the validation context. -func (v *Validation) Error(message string, args ...interface{}) *ValidationResult { - result := (&ValidationResult{ +// Error Add an error to the validation context. +func (v *Validation) Error(message string, args ...interface{}) *Result { + result := (&Result{ Ok: false, - Error: &ValidationError{}, + Error: &Error{}, }).Message(message, args...) v.Errors = append(v.Errors, result.Error) return result } -// Test that the argument is non-nil and non-empty (if string or list) -func (v *Validation) Required(obj interface{}, key string) *ValidationResult { +// Required Test that the argument is non-nil and non-empty (if string or list) +func (v *Validation) Required(obj interface{}, key string) *Result { return v.apply(Required{key}, obj) } -// Test that the obj is greater than min if obj's type is int -func (v *Validation) Min(obj interface{}, min int, key string) *ValidationResult { +// Min Test that the obj is greater than min if obj's type is int +func (v *Validation) Min(obj interface{}, min int, key string) *Result { return v.apply(Min{min, key}, obj) } -// Test that the obj is less than max if obj's type is int -func (v *Validation) Max(obj interface{}, max int, key string) *ValidationResult { +// Max Test that the obj is less than max if obj's type is int +func (v *Validation) Max(obj interface{}, max int, key string) *Result { return v.apply(Max{max, key}, obj) } -// Test that the obj is between mni and max if obj's type is int -func (v *Validation) Range(obj interface{}, min, max int, key string) *ValidationResult { +// Range Test that the obj is between mni and max if obj's type is int +func (v *Validation) Range(obj interface{}, min, max int, key string) *Result { return v.apply(Range{Min{Min: min}, Max{Max: max}, key}, obj) } -// Test that the obj is longer than min size if type is string or slice -func (v *Validation) MinSize(obj interface{}, min int, key string) *ValidationResult { +// MinSize Test that the obj is longer than min size if type is string or slice +func (v *Validation) MinSize(obj interface{}, min int, key string) *Result { return v.apply(MinSize{min, key}, obj) } -// Test that the obj is shorter than max size if type is string or slice -func (v *Validation) MaxSize(obj interface{}, max int, key string) *ValidationResult { +// MaxSize Test that the obj is shorter than max size if type is string or slice +func (v *Validation) MaxSize(obj interface{}, max int, key string) *Result { return v.apply(MaxSize{max, key}, obj) } -// Test that the obj is same length to n if type is string or slice -func (v *Validation) Length(obj interface{}, n int, key string) *ValidationResult { +// Length Test that the obj is same length to n if type is string or slice +func (v *Validation) Length(obj interface{}, n int, key string) *Result { return v.apply(Length{n, key}, obj) } -// Test that the obj is [a-zA-Z] if type is string -func (v *Validation) Alpha(obj interface{}, key string) *ValidationResult { +// Alpha Test that the obj is [a-zA-Z] if type is string +func (v *Validation) Alpha(obj interface{}, key string) *Result { return v.apply(Alpha{key}, obj) } -// Test that the obj is [0-9] if type is string -func (v *Validation) Numeric(obj interface{}, key string) *ValidationResult { +// Numeric Test that the obj is [0-9] if type is string +func (v *Validation) Numeric(obj interface{}, key string) *Result { return v.apply(Numeric{key}, obj) } -// Test that the obj is [0-9a-zA-Z] if type is string -func (v *Validation) AlphaNumeric(obj interface{}, key string) *ValidationResult { +// AlphaNumeric Test that the obj is [0-9a-zA-Z] if type is string +func (v *Validation) AlphaNumeric(obj interface{}, key string) *Result { return v.apply(AlphaNumeric{key}, obj) } -// Test that the obj matches regexp if type is string -func (v *Validation) Match(obj interface{}, regex *regexp.Regexp, key string) *ValidationResult { +// Match Test that the obj matches regexp if type is string +func (v *Validation) Match(obj interface{}, regex *regexp.Regexp, key string) *Result { return v.apply(Match{regex, key}, obj) } -// Test that the obj doesn't match regexp if type is string -func (v *Validation) NoMatch(obj interface{}, regex *regexp.Regexp, key string) *ValidationResult { +// NoMatch Test that the obj doesn't match regexp if type is string +func (v *Validation) NoMatch(obj interface{}, regex *regexp.Regexp, key string) *Result { return v.apply(NoMatch{Match{Regexp: regex}, key}, obj) } -// Test that the obj is [0-9a-zA-Z_-] if type is string -func (v *Validation) AlphaDash(obj interface{}, key string) *ValidationResult { +// AlphaDash Test that the obj is [0-9a-zA-Z_-] if type is string +func (v *Validation) AlphaDash(obj interface{}, key string) *Result { return v.apply(AlphaDash{NoMatch{Match: Match{Regexp: alphaDashPattern}}, key}, obj) } -// Test that the obj is email address if type is string -func (v *Validation) Email(obj interface{}, key string) *ValidationResult { +// Email Test that the obj is email address if type is string +func (v *Validation) Email(obj interface{}, key string) *Result { return v.apply(Email{Match{Regexp: emailPattern}, key}, obj) } -// Test that the obj is IP address if type is string -func (v *Validation) IP(obj interface{}, key string) *ValidationResult { +// IP Test that the obj is IP address if type is string +func (v *Validation) IP(obj interface{}, key string) *Result { return v.apply(IP{Match{Regexp: ipPattern}, key}, obj) } -// Test that the obj is base64 encoded if type is string -func (v *Validation) Base64(obj interface{}, key string) *ValidationResult { +// Base64 Test that the obj is base64 encoded if type is string +func (v *Validation) Base64(obj interface{}, key string) *Result { return v.apply(Base64{Match{Regexp: base64Pattern}, key}, obj) } -// Test that the obj is chinese mobile number if type is string -func (v *Validation) Mobile(obj interface{}, key string) *ValidationResult { +// Mobile Test that the obj is chinese mobile number if type is string +func (v *Validation) Mobile(obj interface{}, key string) *Result { return v.apply(Mobile{Match{Regexp: mobilePattern}, key}, obj) } -// Test that the obj is chinese telephone number if type is string -func (v *Validation) Tel(obj interface{}, key string) *ValidationResult { +// Tel Test that the obj is chinese telephone number if type is string +func (v *Validation) Tel(obj interface{}, key string) *Result { return v.apply(Tel{Match{Regexp: telPattern}, key}, obj) } -// Test that the obj is chinese mobile or telephone number if type is string -func (v *Validation) Phone(obj interface{}, key string) *ValidationResult { +// Phone Test that the obj is chinese mobile or telephone number if type is string +func (v *Validation) Phone(obj interface{}, key string) *Result { return v.apply(Phone{Mobile{Match: Match{Regexp: mobilePattern}}, Tel{Match: Match{Regexp: telPattern}}, key}, obj) } -// Test that the obj is chinese zip code if type is string -func (v *Validation) ZipCode(obj interface{}, key string) *ValidationResult { +// ZipCode Test that the obj is chinese zip code if type is string +func (v *Validation) ZipCode(obj interface{}, key string) *Result { return v.apply(ZipCode{Match{Regexp: zipCodePattern}, key}, obj) } -func (v *Validation) apply(chk Validator, obj interface{}) *ValidationResult { +func (v *Validation) apply(chk Validator, obj interface{}) *Result { if chk.IsSatisfied(obj) { - return &ValidationResult{Ok: true} + return &Result{Ok: true} } // Add the error to the validation context. @@ -249,7 +251,7 @@ func (v *Validation) apply(chk Validator, obj interface{}) *ValidationResult { Name = parts[1] } - err := &ValidationError{ + err := &Error{ Message: chk.DefaultMessage(), Key: key, Name: Name, @@ -261,34 +263,34 @@ func (v *Validation) apply(chk Validator, obj interface{}) *ValidationResult { v.setError(err) // Also return it in the result. - return &ValidationResult{ + return &Result{ Ok: false, Error: err, } } -func (v *Validation) setError(err *ValidationError) { +func (v *Validation) setError(err *Error) { v.Errors = append(v.Errors, err) if v.ErrorsMap == nil { - v.ErrorsMap = make(map[string]*ValidationError) + v.ErrorsMap = make(map[string]*Error) } if _, ok := v.ErrorsMap[err.Field]; !ok { v.ErrorsMap[err.Field] = err } } -// Set error message for one field in ValidationError -func (v *Validation) SetError(fieldName string, errMsg string) *ValidationError { - err := &ValidationError{Key: fieldName, Field: fieldName, Tmpl: errMsg, Message: errMsg} +// SetError Set error message for one field in ValidationError +func (v *Validation) SetError(fieldName string, errMsg string) *Error { + err := &Error{Key: fieldName, Field: fieldName, Tmpl: errMsg, Message: errMsg} v.setError(err) return err } -// Apply a group of validators to a field, in order, and return the +// Check 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 +func (v *Validation) Check(obj interface{}, checks ...Validator) *Result { + var result *Result for _, check := range checks { result = v.apply(check, obj) if !result.Ok { @@ -298,7 +300,7 @@ func (v *Validation) Check(obj interface{}, checks ...Validator) *ValidationResu return result } -// Validate a struct. +// Valid Validate a struct. // the obj parameter must be a struct or a struct pointer func (v *Validation) Valid(obj interface{}) (b bool, err error) { objT := reflect.TypeOf(obj) @@ -335,7 +337,7 @@ func (v *Validation) Valid(obj interface{}) (b bool, err error) { return !v.HasErrors(), nil } -// Recursively validate a struct. +// RecursiveValid Recursively validate a struct. // Step1: Validate by v.Valid // Step2: If pass on step1, then reflect obj's fields // Step3: Do the Recursively validation to all struct or struct pointer fields @@ -345,30 +347,28 @@ func (v *Validation) RecursiveValid(objc interface{}) (bool, error) { pass, err := v.Valid(objc) if err != nil || false == pass { return pass, err // Stop recursive validation - } else { //pass - // Step 2: Validate struct's struct fields - objT := reflect.TypeOf(objc) - objV := reflect.ValueOf(objc) + } + // Step 2: Validate struct's struct fields + objT := reflect.TypeOf(objc) + objV := reflect.ValueOf(objc) - if isStructPtr(objT) { - objT = objT.Elem() - objV = objV.Elem() - } + if isStructPtr(objT) { + objT = objT.Elem() + objV = objV.Elem() + } - for i := 0; i < objT.NumField(); i++ { + for i := 0; i < objT.NumField(); i++ { - t := objT.Field(i).Type + t := objT.Field(i).Type - // Recursive applies to struct or pointer to structs fields - if isStruct(t) || isStructPtr(t) { - // Step 3: do the recursive validation - // Only valid the Public field recursively - if objV.Field(i).CanInterface() { - pass, err = v.RecursiveValid(objV.Field(i).Interface()) - } + // Recursive applies to struct or pointer to structs fields + if isStruct(t) || isStructPtr(t) { + // Step 3: do the recursive validation + // Only valid the Public field recursively + if objV.Field(i).CanInterface() { + pass, err = v.RecursiveValid(objV.Field(i).Interface()) } } - - return pass, err } + return pass, err } diff --git a/validation/validation_test.go b/validation/validation_test.go index d07b1435..ec65b6d0 100644 --- a/validation/validation_test.go +++ b/validation/validation_test.go @@ -302,7 +302,7 @@ func TestZipCode(t *testing.T) { func TestValid(t *testing.T) { type user struct { - Id int + ID int Name string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"` Age int `valid:"Required;Range(1, 140)"` } @@ -352,13 +352,13 @@ func TestValid(t *testing.T) { func TestRecursiveValid(t *testing.T) { type User struct { - Id int + ID int Name string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"` Age int `valid:"Required;Range(1, 140)"` } type AnonymouseUser struct { - Id2 int + ID2 int Name2 string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"` Age2 int `valid:"Required;Range(1, 140)"` } diff --git a/validation/validators.go b/validation/validators.go index 2dcec356..ec1545fb 100644 --- a/validation/validators.go +++ b/validation/validators.go @@ -22,6 +22,7 @@ import ( "unicode/utf8" ) +// MessageTmpls store commond validate template var MessageTmpls = map[string]string{ "Required": "Can not be empty", "Min": "Minimum is %d", @@ -45,6 +46,7 @@ var MessageTmpls = map[string]string{ "ZipCode": "Must be valid zipcode", } +// Validator interface type Validator interface { IsSatisfied(interface{}) bool DefaultMessage() string @@ -52,10 +54,12 @@ type Validator interface { GetLimitValue() interface{} } +// Required struct type Required struct { Key string } +// IsSatisfied judge whether obj has value func (r Required) IsSatisfied(obj interface{}) bool { if obj == nil { return false @@ -80,23 +84,28 @@ func (r Required) IsSatisfied(obj interface{}) bool { return true } +// DefaultMessage return the default error message func (r Required) DefaultMessage() string { return fmt.Sprint(MessageTmpls["Required"]) } +// GetKey return the r.Key func (r Required) GetKey() string { return r.Key } +// GetLimitValue return nil now func (r Required) GetLimitValue() interface{} { return nil } +// Min check struct type Min struct { Min int Key string } +// IsSatisfied judge whether obj is valid func (m Min) IsSatisfied(obj interface{}) bool { num, ok := obj.(int) if ok { @@ -105,23 +114,28 @@ func (m Min) IsSatisfied(obj interface{}) bool { return false } +// DefaultMessage return the default min error message func (m Min) DefaultMessage() string { return fmt.Sprintf(MessageTmpls["Min"], m.Min) } +// GetKey return the m.Key func (m Min) GetKey() string { return m.Key } +// GetLimitValue return the limit value, Min func (m Min) GetLimitValue() interface{} { return m.Min } +// Max validate struct type Max struct { Max int Key string } +// IsSatisfied judge whether obj is valid func (m Max) IsSatisfied(obj interface{}) bool { num, ok := obj.(int) if ok { @@ -130,47 +144,55 @@ func (m Max) IsSatisfied(obj interface{}) bool { return false } +// DefaultMessage return the default max error message func (m Max) DefaultMessage() string { return fmt.Sprintf(MessageTmpls["Max"], m.Max) } +// GetKey return the m.Key func (m Max) GetKey() string { return m.Key } +// GetLimitValue return the limit value, Max func (m Max) GetLimitValue() interface{} { return m.Max } -// Requires an integer to be within Min, Max inclusive. +// Range Requires an integer to be within Min, Max inclusive. type Range struct { Min Max Key string } +// IsSatisfied judge whether obj is valid func (r Range) IsSatisfied(obj interface{}) bool { return r.Min.IsSatisfied(obj) && r.Max.IsSatisfied(obj) } +// DefaultMessage return the default Range error message func (r Range) DefaultMessage() string { return fmt.Sprintf(MessageTmpls["Range"], r.Min.Min, r.Max.Max) } +// GetKey return the m.Key func (r Range) GetKey() string { return r.Key } +// GetLimitValue return the limit value, Max func (r Range) GetLimitValue() interface{} { return []int{r.Min.Min, r.Max.Max} } -// Requires an array or string to be at least a given length. +// MinSize Requires an array or string to be at least a given length. type MinSize struct { Min int Key string } +// IsSatisfied judge whether obj is valid func (m MinSize) IsSatisfied(obj interface{}) bool { if str, ok := obj.(string); ok { return utf8.RuneCountInString(str) >= m.Min @@ -182,24 +204,28 @@ func (m MinSize) IsSatisfied(obj interface{}) bool { return false } +// DefaultMessage return the default MinSize error message func (m MinSize) DefaultMessage() string { return fmt.Sprintf(MessageTmpls["MinSize"], m.Min) } +// GetKey return the m.Key func (m MinSize) GetKey() string { return m.Key } +// GetLimitValue return the limit value func (m MinSize) GetLimitValue() interface{} { return m.Min } -// Requires an array or string to be at most a given length. +// MaxSize Requires an array or string to be at most a given length. type MaxSize struct { Max int Key string } +// IsSatisfied judge whether obj is valid func (m MaxSize) IsSatisfied(obj interface{}) bool { if str, ok := obj.(string); ok { return utf8.RuneCountInString(str) <= m.Max @@ -211,24 +237,28 @@ func (m MaxSize) IsSatisfied(obj interface{}) bool { return false } +// DefaultMessage return the default MaxSize error message func (m MaxSize) DefaultMessage() string { return fmt.Sprintf(MessageTmpls["MaxSize"], m.Max) } +// GetKey return the m.Key func (m MaxSize) GetKey() string { return m.Key } +// GetLimitValue return the limit value func (m MaxSize) GetLimitValue() interface{} { return m.Max } -// Requires an array or string to be exactly a given length. +// Length Requires an array or string to be exactly a given length. type Length struct { N int Key string } +// IsSatisfied judge whether obj is valid func (l Length) IsSatisfied(obj interface{}) bool { if str, ok := obj.(string); ok { return utf8.RuneCountInString(str) == l.N @@ -240,22 +270,27 @@ func (l Length) IsSatisfied(obj interface{}) bool { return false } +// DefaultMessage return the default Length error message func (l Length) DefaultMessage() string { return fmt.Sprintf(MessageTmpls["Length"], l.N) } +// GetKey return the m.Key func (l Length) GetKey() string { return l.Key } +// GetLimitValue return the limit value func (l Length) GetLimitValue() interface{} { return l.N } +// Alpha check the alpha type Alpha struct { Key string } +// IsSatisfied judge whether obj is valid func (a Alpha) IsSatisfied(obj interface{}) bool { if str, ok := obj.(string); ok { for _, v := range str { @@ -268,22 +303,27 @@ func (a Alpha) IsSatisfied(obj interface{}) bool { return false } +// DefaultMessage return the default Length error message func (a Alpha) DefaultMessage() string { return fmt.Sprint(MessageTmpls["Alpha"]) } +// GetKey return the m.Key func (a Alpha) GetKey() string { return a.Key } +// GetLimitValue return the limit value func (a Alpha) GetLimitValue() interface{} { return nil } +// Numeric check number type Numeric struct { Key string } +// IsSatisfied judge whether obj is valid func (n Numeric) IsSatisfied(obj interface{}) bool { if str, ok := obj.(string); ok { for _, v := range str { @@ -296,22 +336,27 @@ func (n Numeric) IsSatisfied(obj interface{}) bool { return false } +// DefaultMessage return the default Length error message func (n Numeric) DefaultMessage() string { return fmt.Sprint(MessageTmpls["Numeric"]) } +// GetKey return the n.Key func (n Numeric) GetKey() string { return n.Key } +// GetLimitValue return the limit value func (n Numeric) GetLimitValue() interface{} { return nil } +// AlphaNumeric check alpha and number type AlphaNumeric struct { Key string } +// IsSatisfied judge whether obj is valid func (a AlphaNumeric) IsSatisfied(obj interface{}) bool { if str, ok := obj.(string); ok { for _, v := range str { @@ -324,134 +369,161 @@ func (a AlphaNumeric) IsSatisfied(obj interface{}) bool { return false } +// DefaultMessage return the default Length error message func (a AlphaNumeric) DefaultMessage() string { return fmt.Sprint(MessageTmpls["AlphaNumeric"]) } +// GetKey return the a.Key func (a AlphaNumeric) GetKey() string { return a.Key } +// GetLimitValue return the limit value func (a AlphaNumeric) GetLimitValue() interface{} { return nil } -// Requires a string to match a given regex. +// Match Requires a string to match a given regex. type Match struct { Regexp *regexp.Regexp Key string } +// IsSatisfied judge whether obj is valid func (m Match) IsSatisfied(obj interface{}) bool { return m.Regexp.MatchString(fmt.Sprintf("%v", obj)) } +// DefaultMessage return the default Match error message func (m Match) DefaultMessage() string { return fmt.Sprintf(MessageTmpls["Match"], m.Regexp.String()) } +// GetKey return the m.Key func (m Match) GetKey() string { return m.Key } +// GetLimitValue return the limit value func (m Match) GetLimitValue() interface{} { return m.Regexp.String() } -// Requires a string to not match a given regex. +// NoMatch Requires a string to not match a given regex. type NoMatch struct { Match Key string } +// IsSatisfied judge whether obj is valid func (n NoMatch) IsSatisfied(obj interface{}) bool { return !n.Match.IsSatisfied(obj) } +// DefaultMessage return the default NoMatch error message func (n NoMatch) DefaultMessage() string { return fmt.Sprintf(MessageTmpls["NoMatch"], n.Regexp.String()) } +// GetKey return the n.Key func (n NoMatch) GetKey() string { return n.Key } +// GetLimitValue return the limit value func (n NoMatch) GetLimitValue() interface{} { return n.Regexp.String() } var alphaDashPattern = regexp.MustCompile("[^\\d\\w-_]") +// AlphaDash check not Alpha type AlphaDash struct { NoMatch Key string } +// DefaultMessage return the default AlphaDash error message func (a AlphaDash) DefaultMessage() string { return fmt.Sprint(MessageTmpls["AlphaDash"]) } +// GetKey return the n.Key func (a AlphaDash) GetKey() string { return a.Key } +// GetLimitValue return the limit value func (a AlphaDash) GetLimitValue() interface{} { return nil } var emailPattern = regexp.MustCompile("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?") +// Email check struct type Email struct { Match Key string } +// DefaultMessage return the default Email error message func (e Email) DefaultMessage() string { return fmt.Sprint(MessageTmpls["Email"]) } +// GetKey return the n.Key func (e Email) GetKey() string { return e.Key } +// GetLimitValue return the limit value func (e Email) GetLimitValue() interface{} { return nil } 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?)$") +// IP check struct type IP struct { Match Key string } +// DefaultMessage return the default IP error message func (i IP) DefaultMessage() string { return fmt.Sprint(MessageTmpls["IP"]) } +// GetKey return the i.Key func (i IP) GetKey() string { return i.Key } +// GetLimitValue return the limit value func (i IP) GetLimitValue() interface{} { return nil } var base64Pattern = regexp.MustCompile("^(?:[A-Za-z0-99+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$") +// Base64 check struct type Base64 struct { Match Key string } +// DefaultMessage return the default Base64 error message func (b Base64) DefaultMessage() string { return fmt.Sprint(MessageTmpls["Base64"]) } +// GetKey return the b.Key func (b Base64) GetKey() string { return b.Key } +// GetLimitValue return the limit value func (b Base64) GetLimitValue() interface{} { return nil } @@ -459,19 +531,23 @@ func (b Base64) GetLimitValue() interface{} { // just for chinese mobile phone number var mobilePattern = regexp.MustCompile("^((\\+86)|(86))?(1(([35][0-9])|[8][0-9]|[7][067]|[4][579]))\\d{8}$") +// Mobile check struct type Mobile struct { Match Key string } +// DefaultMessage return the default Mobile error message func (m Mobile) DefaultMessage() string { return fmt.Sprint(MessageTmpls["Mobile"]) } +// GetKey return the m.Key func (m Mobile) GetKey() string { return m.Key } +// GetLimitValue return the limit value func (m Mobile) GetLimitValue() interface{} { return nil } @@ -479,42 +555,50 @@ func (m Mobile) GetLimitValue() interface{} { // just for chinese telephone number var telPattern = regexp.MustCompile("^(0\\d{2,3}(\\-)?)?\\d{7,8}$") +// Tel check telephone struct type Tel struct { Match Key string } +// DefaultMessage return the default Tel error message func (t Tel) DefaultMessage() string { return fmt.Sprint(MessageTmpls["Tel"]) } +// GetKey return the t.Key func (t Tel) GetKey() string { return t.Key } +// GetLimitValue return the limit value func (t Tel) GetLimitValue() interface{} { return nil } -// just for chinese telephone or mobile phone number +// Phone just for chinese telephone or mobile phone number type Phone struct { Mobile Tel Key string } +// IsSatisfied judge whether obj is valid func (p Phone) IsSatisfied(obj interface{}) bool { return p.Mobile.IsSatisfied(obj) || p.Tel.IsSatisfied(obj) } +// DefaultMessage return the default Phone error message func (p Phone) DefaultMessage() string { return fmt.Sprint(MessageTmpls["Phone"]) } +// GetKey return the p.Key func (p Phone) GetKey() string { return p.Key } +// GetLimitValue return the limit value func (p Phone) GetLimitValue() interface{} { return nil } @@ -522,19 +606,23 @@ func (p Phone) GetLimitValue() interface{} { // just for chinese zipcode var zipCodePattern = regexp.MustCompile("^[1-9]\\d{5}$") +// ZipCode check the zip struct type ZipCode struct { Match Key string } +// DefaultMessage return the default Zip error message func (z ZipCode) DefaultMessage() string { return fmt.Sprint(MessageTmpls["ZipCode"]) } +// GetKey return the z.Key func (z ZipCode) GetKey() string { return z.Key } +// GetLimitValue return the limit value func (z ZipCode) GetLimitValue() interface{} { return nil }