ea9c2ceb by slene

validation add more info to ValidationError, and put all messages tmpl to a map

1 parent 02a03cec
...@@ -4,10 +4,13 @@ import ( ...@@ -4,10 +4,13 @@ import (
4 "fmt" 4 "fmt"
5 "reflect" 5 "reflect"
6 "regexp" 6 "regexp"
7 "strings"
7 ) 8 )
8 9
9 type ValidationError struct { 10 type ValidationError struct {
10 Message, Key string 11 Message, Key, Name, Field, Tmpl string
12 Value interface{}
13 LimitValue interface{}
11 } 14 }
12 15
13 // Returns the Message. 16 // Returns the Message.
...@@ -170,9 +173,24 @@ func (v *Validation) apply(chk Validator, obj interface{}) *ValidationResult { ...@@ -170,9 +173,24 @@ func (v *Validation) apply(chk Validator, obj interface{}) *ValidationResult {
170 } 173 }
171 174
172 // Add the error to the validation context. 175 // Add the error to the validation context.
176 key := chk.GetKey()
177 Name := key
178 Field := ""
179
180 parts := strings.Split(key, ".")
181 if len(parts) == 2 {
182 Field = parts[0]
183 Name = parts[1]
184 }
185
173 err := &ValidationError{ 186 err := &ValidationError{
174 Message: chk.DefaultMessage(), 187 Message: chk.DefaultMessage(),
175 Key: chk.GetKey(), 188 Key: key,
189 Name: Name,
190 Field: Field,
191 Value: obj,
192 Tmpl: MessageTmpls[Name],
193 LimitValue: chk.GetLimitValue(),
176 } 194 }
177 v.Errors = append(v.Errors, err) 195 v.Errors = append(v.Errors, err)
178 196
......
...@@ -7,10 +7,34 @@ import ( ...@@ -7,10 +7,34 @@ import (
7 "time" 7 "time"
8 ) 8 )
9 9
10 var MessageTmpls = map[string]string{
11 "Required": "Can not be empty",
12 "Min": "Minimum is %d",
13 "Max": "Maximum is %d",
14 "Range": "Range is %d to %d",
15 "MinSize": "Minimum size is %d",
16 "MaxSize": "Maximum size is %d",
17 "Length": "Required length is %d",
18 "Alpha": "Must be valid alpha characters",
19 "Numeric": "Must be valid numeric characters",
20 "AlphaNumeric": "Must be valid alpha or numeric characters",
21 "Match": "Must match %s",
22 "NoMatch": "Must not match %s",
23 "AlphaDash": "Must be valid alpha or numeric or dash(-_) characters",
24 "Email": "Must be a valid email address",
25 "IP": "Must be a valid ip address",
26 "Base64": "Must be valid base64 characters",
27 "Mobile": "Must be valid mobile number",
28 "Tel": "Must be valid telephone number",
29 "Phone": "Must be valid telephone or mobile phone number",
30 "ZipCode": "Must be valid zipcode",
31 }
32
10 type Validator interface { 33 type Validator interface {
11 IsSatisfied(interface{}) bool 34 IsSatisfied(interface{}) bool
12 DefaultMessage() string 35 DefaultMessage() string
13 GetKey() string 36 GetKey() string
37 GetLimitValue() interface{}
14 } 38 }
15 39
16 type Required struct { 40 type Required struct {
...@@ -49,6 +73,10 @@ func (r Required) GetKey() string { ...@@ -49,6 +73,10 @@ func (r Required) GetKey() string {
49 return r.Key 73 return r.Key
50 } 74 }
51 75
76 func (r Required) GetLimitValue() interface{} {
77 return nil
78 }
79
52 type Min struct { 80 type Min struct {
53 Min int 81 Min int
54 Key string 82 Key string
...@@ -63,13 +91,17 @@ func (m Min) IsSatisfied(obj interface{}) bool { ...@@ -63,13 +91,17 @@ func (m Min) IsSatisfied(obj interface{}) bool {
63 } 91 }
64 92
65 func (m Min) DefaultMessage() string { 93 func (m Min) DefaultMessage() string {
66 return fmt.Sprint("Minimum is ", m.Min) 94 return fmt.Sprintf(MessageTmpls["Min"], m.Min)
67 } 95 }
68 96
69 func (m Min) GetKey() string { 97 func (m Min) GetKey() string {
70 return m.Key 98 return m.Key
71 } 99 }
72 100
101 func (m Min) GetLimitValue() interface{} {
102 return m.Min
103 }
104
73 type Max struct { 105 type Max struct {
74 Max int 106 Max int
75 Key string 107 Key string
...@@ -84,13 +116,17 @@ func (m Max) IsSatisfied(obj interface{}) bool { ...@@ -84,13 +116,17 @@ func (m Max) IsSatisfied(obj interface{}) bool {
84 } 116 }
85 117
86 func (m Max) DefaultMessage() string { 118 func (m Max) DefaultMessage() string {
87 return fmt.Sprint("Maximum is ", m.Max) 119 return fmt.Sprintf(MessageTmpls["Max"], m.Max)
88 } 120 }
89 121
90 func (m Max) GetKey() string { 122 func (m Max) GetKey() string {
91 return m.Key 123 return m.Key
92 } 124 }
93 125
126 func (m Max) GetLimitValue() interface{} {
127 return m.Max
128 }
129
94 // Requires an integer to be within Min, Max inclusive. 130 // Requires an integer to be within Min, Max inclusive.
95 type Range struct { 131 type Range struct {
96 Min 132 Min
...@@ -103,13 +139,17 @@ func (r Range) IsSatisfied(obj interface{}) bool { ...@@ -103,13 +139,17 @@ func (r Range) IsSatisfied(obj interface{}) bool {
103 } 139 }
104 140
105 func (r Range) DefaultMessage() string { 141 func (r Range) DefaultMessage() string {
106 return fmt.Sprint("Range is ", r.Min.Min, " to ", r.Max.Max) 142 return fmt.Sprintf(MessageTmpls["Range"], r.Min.Min, r.Max.Max)
107 } 143 }
108 144
109 func (r Range) GetKey() string { 145 func (r Range) GetKey() string {
110 return r.Key 146 return r.Key
111 } 147 }
112 148
149 func (r Range) GetLimitValue() interface{} {
150 return []int{r.Min.Min, r.Max.Max}
151 }
152
113 // Requires an array or string to be at least a given length. 153 // Requires an array or string to be at least a given length.
114 type MinSize struct { 154 type MinSize struct {
115 Min int 155 Min int
...@@ -128,13 +168,17 @@ func (m MinSize) IsSatisfied(obj interface{}) bool { ...@@ -128,13 +168,17 @@ func (m MinSize) IsSatisfied(obj interface{}) bool {
128 } 168 }
129 169
130 func (m MinSize) DefaultMessage() string { 170 func (m MinSize) DefaultMessage() string {
131 return fmt.Sprint("Minimum size is ", m.Min) 171 return fmt.Sprintf(MessageTmpls["MinSize"], m.Min)
132 } 172 }
133 173
134 func (m MinSize) GetKey() string { 174 func (m MinSize) GetKey() string {
135 return m.Key 175 return m.Key
136 } 176 }
137 177
178 func (m MinSize) GetLimitValue() interface{} {
179 return m.Min
180 }
181
138 // Requires an array or string to be at most a given length. 182 // Requires an array or string to be at most a given length.
139 type MaxSize struct { 183 type MaxSize struct {
140 Max int 184 Max int
...@@ -153,13 +197,17 @@ func (m MaxSize) IsSatisfied(obj interface{}) bool { ...@@ -153,13 +197,17 @@ func (m MaxSize) IsSatisfied(obj interface{}) bool {
153 } 197 }
154 198
155 func (m MaxSize) DefaultMessage() string { 199 func (m MaxSize) DefaultMessage() string {
156 return fmt.Sprint("Maximum size is ", m.Max) 200 return fmt.Sprintf(MessageTmpls["MaxSize"], m.Max)
157 } 201 }
158 202
159 func (m MaxSize) GetKey() string { 203 func (m MaxSize) GetKey() string {
160 return m.Key 204 return m.Key
161 } 205 }
162 206
207 func (m MaxSize) GetLimitValue() interface{} {
208 return m.Max
209 }
210
163 // Requires an array or string to be exactly a given length. 211 // Requires an array or string to be exactly a given length.
164 type Length struct { 212 type Length struct {
165 N int 213 N int
...@@ -178,13 +226,17 @@ func (l Length) IsSatisfied(obj interface{}) bool { ...@@ -178,13 +226,17 @@ func (l Length) IsSatisfied(obj interface{}) bool {
178 } 226 }
179 227
180 func (l Length) DefaultMessage() string { 228 func (l Length) DefaultMessage() string {
181 return fmt.Sprint("Required length is ", l.N) 229 return fmt.Sprintf(MessageTmpls["Length"], l.N)
182 } 230 }
183 231
184 func (l Length) GetKey() string { 232 func (l Length) GetKey() string {
185 return l.Key 233 return l.Key
186 } 234 }
187 235
236 func (l Length) GetLimitValue() interface{} {
237 return l.N
238 }
239
188 type Alpha struct { 240 type Alpha struct {
189 Key string 241 Key string
190 } 242 }
...@@ -202,13 +254,17 @@ func (a Alpha) IsSatisfied(obj interface{}) bool { ...@@ -202,13 +254,17 @@ func (a Alpha) IsSatisfied(obj interface{}) bool {
202 } 254 }
203 255
204 func (a Alpha) DefaultMessage() string { 256 func (a Alpha) DefaultMessage() string {
205 return fmt.Sprint("Must be valid alpha characters") 257 return fmt.Sprint(MessageTmpls["Alpha"])
206 } 258 }
207 259
208 func (a Alpha) GetKey() string { 260 func (a Alpha) GetKey() string {
209 return a.Key 261 return a.Key
210 } 262 }
211 263
264 func (a Alpha) GetLimitValue() interface{} {
265 return nil
266 }
267
212 type Numeric struct { 268 type Numeric struct {
213 Key string 269 Key string
214 } 270 }
...@@ -226,13 +282,17 @@ func (n Numeric) IsSatisfied(obj interface{}) bool { ...@@ -226,13 +282,17 @@ func (n Numeric) IsSatisfied(obj interface{}) bool {
226 } 282 }
227 283
228 func (n Numeric) DefaultMessage() string { 284 func (n Numeric) DefaultMessage() string {
229 return fmt.Sprint("Must be valid numeric characters") 285 return fmt.Sprint(MessageTmpls["Numeric"])
230 } 286 }
231 287
232 func (n Numeric) GetKey() string { 288 func (n Numeric) GetKey() string {
233 return n.Key 289 return n.Key
234 } 290 }
235 291
292 func (n Numeric) GetLimitValue() interface{} {
293 return nil
294 }
295
236 type AlphaNumeric struct { 296 type AlphaNumeric struct {
237 Key string 297 Key string
238 } 298 }
...@@ -250,13 +310,17 @@ func (a AlphaNumeric) IsSatisfied(obj interface{}) bool { ...@@ -250,13 +310,17 @@ func (a AlphaNumeric) IsSatisfied(obj interface{}) bool {
250 } 310 }
251 311
252 func (a AlphaNumeric) DefaultMessage() string { 312 func (a AlphaNumeric) DefaultMessage() string {
253 return fmt.Sprint("Must be valid alpha or numeric characters") 313 return fmt.Sprint(MessageTmpls["AlphaNumeric"])
254 } 314 }
255 315
256 func (a AlphaNumeric) GetKey() string { 316 func (a AlphaNumeric) GetKey() string {
257 return a.Key 317 return a.Key
258 } 318 }
259 319
320 func (a AlphaNumeric) GetLimitValue() interface{} {
321 return nil
322 }
323
260 // Requires a string to match a given regex. 324 // Requires a string to match a given regex.
261 type Match struct { 325 type Match struct {
262 Regexp *regexp.Regexp 326 Regexp *regexp.Regexp
...@@ -268,13 +332,17 @@ func (m Match) IsSatisfied(obj interface{}) bool { ...@@ -268,13 +332,17 @@ func (m Match) IsSatisfied(obj interface{}) bool {
268 } 332 }
269 333
270 func (m Match) DefaultMessage() string { 334 func (m Match) DefaultMessage() string {
271 return fmt.Sprint("Must match ", m.Regexp) 335 return fmt.Sprintf(MessageTmpls["Match"], m.Regexp.String())
272 } 336 }
273 337
274 func (m Match) GetKey() string { 338 func (m Match) GetKey() string {
275 return m.Key 339 return m.Key
276 } 340 }
277 341
342 func (m Match) GetLimitValue() interface{} {
343 return m.Regexp.String()
344 }
345
278 // Requires a string to not match a given regex. 346 // Requires a string to not match a given regex.
279 type NoMatch struct { 347 type NoMatch struct {
280 Match 348 Match
...@@ -286,13 +354,17 @@ func (n NoMatch) IsSatisfied(obj interface{}) bool { ...@@ -286,13 +354,17 @@ func (n NoMatch) IsSatisfied(obj interface{}) bool {
286 } 354 }
287 355
288 func (n NoMatch) DefaultMessage() string { 356 func (n NoMatch) DefaultMessage() string {
289 return fmt.Sprint("Must not match ", n.Regexp) 357 return fmt.Sprintf(MessageTmpls["NoMatch"], n.Regexp.String())
290 } 358 }
291 359
292 func (n NoMatch) GetKey() string { 360 func (n NoMatch) GetKey() string {
293 return n.Key 361 return n.Key
294 } 362 }
295 363
364 func (n NoMatch) GetLimitValue() interface{} {
365 return n.Regexp.String()
366 }
367
296 var alphaDashPattern = regexp.MustCompile("[^\\d\\w-_]") 368 var alphaDashPattern = regexp.MustCompile("[^\\d\\w-_]")
297 369
298 type AlphaDash struct { 370 type AlphaDash struct {
...@@ -301,13 +373,17 @@ type AlphaDash struct { ...@@ -301,13 +373,17 @@ type AlphaDash struct {
301 } 373 }
302 374
303 func (a AlphaDash) DefaultMessage() string { 375 func (a AlphaDash) DefaultMessage() string {
304 return fmt.Sprint("Must be valid alpha or numeric or dash(-_) characters") 376 return fmt.Sprint(MessageTmpls["AlphaDash"])
305 } 377 }
306 378
307 func (a AlphaDash) GetKey() string { 379 func (a AlphaDash) GetKey() string {
308 return a.Key 380 return a.Key
309 } 381 }
310 382
383 func (a AlphaDash) GetLimitValue() interface{} {
384 return nil
385 }
386
311 var emailPattern = regexp.MustCompile("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?") 387 var emailPattern = regexp.MustCompile("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?")
312 388
313 type Email struct { 389 type Email struct {
...@@ -316,13 +392,17 @@ type Email struct { ...@@ -316,13 +392,17 @@ type Email struct {
316 } 392 }
317 393
318 func (e Email) DefaultMessage() string { 394 func (e Email) DefaultMessage() string {
319 return fmt.Sprint("Must be a valid email address") 395 return fmt.Sprint(MessageTmpls["Email"])
320 } 396 }
321 397
322 func (e Email) GetKey() string { 398 func (e Email) GetKey() string {
323 return e.Key 399 return e.Key
324 } 400 }
325 401
402 func (e Email) GetLimitValue() interface{} {
403 return nil
404 }
405
326 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?)$") 406 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?)$")
327 407
328 type IP struct { 408 type IP struct {
...@@ -331,13 +411,17 @@ type IP struct { ...@@ -331,13 +411,17 @@ type IP struct {
331 } 411 }
332 412
333 func (i IP) DefaultMessage() string { 413 func (i IP) DefaultMessage() string {
334 return fmt.Sprint("Must be a valid ip address") 414 return fmt.Sprint(MessageTmpls["IP"])
335 } 415 }
336 416
337 func (i IP) GetKey() string { 417 func (i IP) GetKey() string {
338 return i.Key 418 return i.Key
339 } 419 }
340 420
421 func (i IP) GetLimitValue() interface{} {
422 return nil
423 }
424
341 var base64Pattern = regexp.MustCompile("^(?:[A-Za-z0-99+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$") 425 var base64Pattern = regexp.MustCompile("^(?:[A-Za-z0-99+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$")
342 426
343 type Base64 struct { 427 type Base64 struct {
...@@ -346,13 +430,17 @@ type Base64 struct { ...@@ -346,13 +430,17 @@ type Base64 struct {
346 } 430 }
347 431
348 func (b Base64) DefaultMessage() string { 432 func (b Base64) DefaultMessage() string {
349 return fmt.Sprint("Must be valid base64 characters") 433 return fmt.Sprint(MessageTmpls["Base64"])
350 } 434 }
351 435
352 func (b Base64) GetKey() string { 436 func (b Base64) GetKey() string {
353 return b.Key 437 return b.Key
354 } 438 }
355 439
440 func (b Base64) GetLimitValue() interface{} {
441 return nil
442 }
443
356 // just for chinese mobile phone number 444 // just for chinese mobile phone number
357 var mobilePattern = regexp.MustCompile("^((\\+86)|(86))?(1(([35][0-9])|(47)|[8][01236789]))\\d{8}$") 445 var mobilePattern = regexp.MustCompile("^((\\+86)|(86))?(1(([35][0-9])|(47)|[8][01236789]))\\d{8}$")
358 446
...@@ -362,13 +450,17 @@ type Mobile struct { ...@@ -362,13 +450,17 @@ type Mobile struct {
362 } 450 }
363 451
364 func (m Mobile) DefaultMessage() string { 452 func (m Mobile) DefaultMessage() string {
365 return fmt.Sprint("Must be valid mobile number") 453 return fmt.Sprint(MessageTmpls["Mobile"])
366 } 454 }
367 455
368 func (m Mobile) GetKey() string { 456 func (m Mobile) GetKey() string {
369 return m.Key 457 return m.Key
370 } 458 }
371 459
460 func (m Mobile) GetLimitValue() interface{} {
461 return nil
462 }
463
372 // just for chinese telephone number 464 // just for chinese telephone number
373 var telPattern = regexp.MustCompile("^(0\\d{2,3}(\\-)?)?\\d{7,8}$") 465 var telPattern = regexp.MustCompile("^(0\\d{2,3}(\\-)?)?\\d{7,8}$")
374 466
...@@ -378,13 +470,17 @@ type Tel struct { ...@@ -378,13 +470,17 @@ type Tel struct {
378 } 470 }
379 471
380 func (t Tel) DefaultMessage() string { 472 func (t Tel) DefaultMessage() string {
381 return fmt.Sprint("Must be valid telephone number") 473 return fmt.Sprint(MessageTmpls["Tel"])
382 } 474 }
383 475
384 func (t Tel) GetKey() string { 476 func (t Tel) GetKey() string {
385 return t.Key 477 return t.Key
386 } 478 }
387 479
480 func (t Tel) GetLimitValue() interface{} {
481 return nil
482 }
483
388 // just for chinese telephone or mobile phone number 484 // just for chinese telephone or mobile phone number
389 type Phone struct { 485 type Phone struct {
390 Mobile 486 Mobile
...@@ -397,13 +493,17 @@ func (p Phone) IsSatisfied(obj interface{}) bool { ...@@ -397,13 +493,17 @@ func (p Phone) IsSatisfied(obj interface{}) bool {
397 } 493 }
398 494
399 func (p Phone) DefaultMessage() string { 495 func (p Phone) DefaultMessage() string {
400 return fmt.Sprint("Must be valid telephone or mobile phone number") 496 return fmt.Sprint(MessageTmpls["Phone"])
401 } 497 }
402 498
403 func (p Phone) GetKey() string { 499 func (p Phone) GetKey() string {
404 return p.Key 500 return p.Key
405 } 501 }
406 502
503 func (p Phone) GetLimitValue() interface{} {
504 return nil
505 }
506
407 // just for chinese zipcode 507 // just for chinese zipcode
408 var zipCodePattern = regexp.MustCompile("^[1-9]\\d{5}$") 508 var zipCodePattern = regexp.MustCompile("^[1-9]\\d{5}$")
409 509
...@@ -413,9 +513,13 @@ type ZipCode struct { ...@@ -413,9 +513,13 @@ type ZipCode struct {
413 } 513 }
414 514
415 func (z ZipCode) DefaultMessage() string { 515 func (z ZipCode) DefaultMessage() string {
416 return fmt.Sprint("Must be valid zipcode") 516 return fmt.Sprint(MessageTmpls["ZipCode"])
417 } 517 }
418 518
419 func (z ZipCode) GetKey() string { 519 func (z ZipCode) GetKey() string {
420 return z.Key 520 return z.Key
421 } 521 }
522
523 func (z ZipCode) GetLimitValue() interface{} {
524 return nil
525 }
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!