add ValidFormer interface, can custom valid
Showing
1 changed file
with
56 additions
and
34 deletions
| ... | @@ -7,6 +7,10 @@ import ( | ... | @@ -7,6 +7,10 @@ import ( |
| 7 | "strings" | 7 | "strings" |
| 8 | ) | 8 | ) |
| 9 | 9 | ||
| 10 | type ValidFormer interface { | ||
| 11 | Valid(*Validation) | ||
| 12 | } | ||
| 13 | |||
| 10 | type ValidationError struct { | 14 | type ValidationError struct { |
| 11 | Message, Key, Name, Field, Tmpl string | 15 | Message, Key, Name, Field, Tmpl string |
| 12 | Value interface{} | 16 | Value interface{} |
| ... | @@ -21,9 +25,35 @@ func (e *ValidationError) String() string { | ... | @@ -21,9 +25,35 @@ func (e *ValidationError) String() string { |
| 21 | return e.Message | 25 | return e.Message |
| 22 | } | 26 | } |
| 23 | 27 | ||
| 28 | // A ValidationResult is returned from every validation method. | ||
| 29 | // It provides an indication of success, and a pointer to the Error (if any). | ||
| 30 | type ValidationResult struct { | ||
| 31 | Error *ValidationError | ||
| 32 | Ok bool | ||
| 33 | } | ||
| 34 | |||
| 35 | func (r *ValidationResult) Key(key string) *ValidationResult { | ||
| 36 | if r.Error != nil { | ||
| 37 | r.Error.Key = key | ||
| 38 | } | ||
| 39 | return r | ||
| 40 | } | ||
| 41 | |||
| 42 | func (r *ValidationResult) Message(message string, args ...interface{}) *ValidationResult { | ||
| 43 | if r.Error != nil { | ||
| 44 | if len(args) == 0 { | ||
| 45 | r.Error.Message = message | ||
| 46 | } else { | ||
| 47 | r.Error.Message = fmt.Sprintf(message, args...) | ||
| 48 | } | ||
| 49 | } | ||
| 50 | return r | ||
| 51 | } | ||
| 52 | |||
| 24 | // A Validation context manages data validation and error messages. | 53 | // A Validation context manages data validation and error messages. |
| 25 | type Validation struct { | 54 | type Validation struct { |
| 26 | Errors []*ValidationError | 55 | Errors []*ValidationError |
| 56 | ErrorsMap map[string]*ValidationError | ||
| 27 | } | 57 | } |
| 28 | 58 | ||
| 29 | func (v *Validation) Clear() { | 59 | func (v *Validation) Clear() { |
| ... | @@ -38,13 +68,7 @@ func (v *Validation) HasErrors() bool { | ... | @@ -38,13 +68,7 @@ func (v *Validation) HasErrors() bool { |
| 38 | // If there are multiple validation errors associated with a single key, the | 68 | // If there are multiple validation errors associated with a single key, the |
| 39 | // first one "wins". (Typically the first validation will be the more basic). | 69 | // first one "wins". (Typically the first validation will be the more basic). |
| 40 | func (v *Validation) ErrorMap() map[string]*ValidationError { | 70 | func (v *Validation) ErrorMap() map[string]*ValidationError { |
| 41 | m := map[string]*ValidationError{} | 71 | return v.ErrorsMap |
| 42 | for _, e := range v.Errors { | ||
| 43 | if _, ok := m[e.Key]; !ok { | ||
| 44 | m[e.Key] = e | ||
| 45 | } | ||
| 46 | } | ||
| 47 | return m | ||
| 48 | } | 72 | } |
| 49 | 73 | ||
| 50 | // Add an error to the validation context. | 74 | // Add an error to the validation context. |
| ... | @@ -57,31 +81,6 @@ func (v *Validation) Error(message string, args ...interface{}) *ValidationResul | ... | @@ -57,31 +81,6 @@ func (v *Validation) Error(message string, args ...interface{}) *ValidationResul |
| 57 | return result | 81 | return result |
| 58 | } | 82 | } |
| 59 | 83 | ||
| 60 | // A ValidationResult is returned from every validation method. | ||
| 61 | // It provides an indication of success, and a pointer to the Error (if any). | ||
| 62 | type ValidationResult struct { | ||
| 63 | Error *ValidationError | ||
| 64 | Ok bool | ||
| 65 | } | ||
| 66 | |||
| 67 | func (r *ValidationResult) Key(key string) *ValidationResult { | ||
| 68 | if r.Error != nil { | ||
| 69 | r.Error.Key = key | ||
| 70 | } | ||
| 71 | return r | ||
| 72 | } | ||
| 73 | |||
| 74 | func (r *ValidationResult) Message(message string, args ...interface{}) *ValidationResult { | ||
| 75 | if r.Error != nil { | ||
| 76 | if len(args) == 0 { | ||
| 77 | r.Error.Message = message | ||
| 78 | } else { | ||
| 79 | r.Error.Message = fmt.Sprintf(message, args...) | ||
| 80 | } | ||
| 81 | } | ||
| 82 | return r | ||
| 83 | } | ||
| 84 | |||
| 85 | // Test that the argument is non-nil and non-empty (if string or list) | 84 | // Test that the argument is non-nil and non-empty (if string or list) |
| 86 | func (v *Validation) Required(obj interface{}, key string) *ValidationResult { | 85 | func (v *Validation) Required(obj interface{}, key string) *ValidationResult { |
| 87 | return v.apply(Required{key}, obj) | 86 | return v.apply(Required{key}, obj) |
| ... | @@ -192,7 +191,7 @@ func (v *Validation) apply(chk Validator, obj interface{}) *ValidationResult { | ... | @@ -192,7 +191,7 @@ func (v *Validation) apply(chk Validator, obj interface{}) *ValidationResult { |
| 192 | Tmpl: MessageTmpls[Name], | 191 | Tmpl: MessageTmpls[Name], |
| 193 | LimitValue: chk.GetLimitValue(), | 192 | LimitValue: chk.GetLimitValue(), |
| 194 | } | 193 | } |
| 195 | v.Errors = append(v.Errors, err) | 194 | v.setError(err) |
| 196 | 195 | ||
| 197 | // Also return it in the result. | 196 | // Also return it in the result. |
| 198 | return &ValidationResult{ | 197 | return &ValidationResult{ |
| ... | @@ -201,6 +200,22 @@ func (v *Validation) apply(chk Validator, obj interface{}) *ValidationResult { | ... | @@ -201,6 +200,22 @@ func (v *Validation) apply(chk Validator, obj interface{}) *ValidationResult { |
| 201 | } | 200 | } |
| 202 | } | 201 | } |
| 203 | 202 | ||
| 203 | func (v *Validation) setError(err *ValidationError) { | ||
| 204 | v.Errors = append(v.Errors, err) | ||
| 205 | if v.ErrorsMap == nil { | ||
| 206 | v.ErrorsMap = make(map[string]*ValidationError) | ||
| 207 | } | ||
| 208 | if _, ok := v.ErrorsMap[err.Field]; !ok { | ||
| 209 | v.ErrorsMap[err.Field] = err | ||
| 210 | } | ||
| 211 | } | ||
| 212 | |||
| 213 | func (v *Validation) SetError(fieldName string, errMsg string) *ValidationError { | ||
| 214 | err := &ValidationError{Key: fieldName, Field: fieldName, Tmpl: errMsg, Message: errMsg} | ||
| 215 | v.setError(err) | ||
| 216 | return err | ||
| 217 | } | ||
| 218 | |||
| 204 | // Apply a group of validators to a field, in order, and return the | 219 | // Apply a group of validators to a field, in order, and return the |
| 205 | // ValidationResult from the first one that fails, or the last one that | 220 | // ValidationResult from the first one that fails, or the last one that |
| 206 | // succeeds. | 221 | // succeeds. |
| ... | @@ -241,5 +256,12 @@ func (v *Validation) Valid(obj interface{}) (b bool, err error) { | ... | @@ -241,5 +256,12 @@ func (v *Validation) Valid(obj interface{}) (b bool, err error) { |
| 241 | } | 256 | } |
| 242 | } | 257 | } |
| 243 | } | 258 | } |
| 259 | |||
| 260 | if !v.HasErrors() { | ||
| 261 | if form, ok := obj.(ValidFormer); ok { | ||
| 262 | form.Valid(v) | ||
| 263 | } | ||
| 264 | } | ||
| 265 | |||
| 244 | return !v.HasErrors(), nil | 266 | return !v.HasErrors(), nil |
| 245 | } | 267 | } | ... | ... |
-
Please register or sign in to post a comment