1 package en
2
3 import (
4 "fmt"
5 "log"
6 "reflect"
7 "strconv"
8 "strings"
9 "time"
10
11 "github.com/go-playground/locales"
12 ut "github.com/go-playground/universal-translator"
13
14 "github.com/go-playground/validator/v10"
15 )
16
17
18
19 func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (err error) {
20 translations := []struct {
21 tag string
22 translation string
23 override bool
24 customRegisFunc validator.RegisterTranslationsFunc
25 customTransFunc validator.TranslationFunc
26 }{
27 {
28 tag: "required",
29 translation: "{0} is a required field",
30 override: false,
31 },
32 {
33 tag: "required_if",
34 translation: "{0} is a required field",
35 override: false,
36 },
37 {
38 tag: "required_unless",
39 translation: "{0} is a required field",
40 override: false,
41 },
42 {
43 tag: "required_with",
44 translation: "{0} is a required field",
45 override: false,
46 },
47 {
48 tag: "required_with_all",
49 translation: "{0} is a required field",
50 override: false,
51 },
52 {
53 tag: "required_without",
54 translation: "{0} is a required field",
55 override: false,
56 },
57 {
58 tag: "required_without_all",
59 translation: "{0} is a required field",
60 override: false,
61 },
62 {
63 tag: "excluded_if",
64 translation: "{0} is an excluded field",
65 override: false,
66 },
67 {
68 tag: "excluded_unless",
69 translation: "{0} is an excluded field",
70 override: false,
71 },
72 {
73 tag: "excluded_with",
74 translation: "{0} is an excluded field",
75 override: false,
76 },
77 {
78 tag: "excluded_with_all",
79 translation: "{0} is an excluded field",
80 override: false,
81 },
82 {
83 tag: "excluded_without",
84 translation: "{0} is an excluded field",
85 override: false,
86 },
87 {
88 tag: "excluded_without_all",
89 translation: "{0} is an excluded field",
90 override: false,
91 },
92 {
93 tag: "isdefault",
94 translation: "{0} must be default value",
95 override: false,
96 },
97 {
98 tag: "len",
99 customRegisFunc: func(ut ut.Translator) (err error) {
100 if err = ut.Add("len-string", "{0} must be {1} in length", false); err != nil {
101 return
102 }
103
104 if err = ut.AddCardinal("len-string-character", "{0} character", locales.PluralRuleOne, false); err != nil {
105 return
106 }
107
108 if err = ut.AddCardinal("len-string-character", "{0} characters", locales.PluralRuleOther, false); err != nil {
109 return
110 }
111
112 if err = ut.Add("len-number", "{0} must be equal to {1}", false); err != nil {
113 return
114 }
115
116 if err = ut.Add("len-items", "{0} must contain {1}", false); err != nil {
117 return
118 }
119 if err = ut.AddCardinal("len-items-item", "{0} item", locales.PluralRuleOne, false); err != nil {
120 return
121 }
122
123 if err = ut.AddCardinal("len-items-item", "{0} items", locales.PluralRuleOther, false); err != nil {
124 return
125 }
126
127 return
128 },
129 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
130 var err error
131 var t string
132
133 var digits uint64
134 var kind reflect.Kind
135
136 if idx := strings.Index(fe.Param(), "."); idx != -1 {
137 digits = uint64(len(fe.Param()[idx+1:]))
138 }
139
140 f64, err := strconv.ParseFloat(fe.Param(), 64)
141 if err != nil {
142 goto END
143 }
144
145 kind = fe.Kind()
146 if kind == reflect.Ptr {
147 kind = fe.Type().Elem().Kind()
148 }
149
150 switch kind {
151 case reflect.String:
152
153 var c string
154
155 c, err = ut.C("len-string-character", f64, digits, ut.FmtNumber(f64, digits))
156 if err != nil {
157 goto END
158 }
159
160 t, err = ut.T("len-string", fe.Field(), c)
161
162 case reflect.Slice, reflect.Map, reflect.Array:
163 var c string
164
165 c, err = ut.C("len-items-item", f64, digits, ut.FmtNumber(f64, digits))
166 if err != nil {
167 goto END
168 }
169
170 t, err = ut.T("len-items", fe.Field(), c)
171
172 default:
173 t, err = ut.T("len-number", fe.Field(), ut.FmtNumber(f64, digits))
174 }
175
176 END:
177 if err != nil {
178 fmt.Printf("warning: error translating FieldError: %s", err)
179 return fe.(error).Error()
180 }
181
182 return t
183 },
184 },
185 {
186 tag: "min",
187 customRegisFunc: func(ut ut.Translator) (err error) {
188 if err = ut.Add("min-string", "{0} must be at least {1} in length", false); err != nil {
189 return
190 }
191
192 if err = ut.AddCardinal("min-string-character", "{0} character", locales.PluralRuleOne, false); err != nil {
193 return
194 }
195
196 if err = ut.AddCardinal("min-string-character", "{0} characters", locales.PluralRuleOther, false); err != nil {
197 return
198 }
199
200 if err = ut.Add("min-number", "{0} must be {1} or greater", false); err != nil {
201 return
202 }
203
204 if err = ut.Add("min-items", "{0} must contain at least {1}", false); err != nil {
205 return
206 }
207 if err = ut.AddCardinal("min-items-item", "{0} item", locales.PluralRuleOne, false); err != nil {
208 return
209 }
210
211 if err = ut.AddCardinal("min-items-item", "{0} items", locales.PluralRuleOther, false); err != nil {
212 return
213 }
214
215 return
216 },
217 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
218 var err error
219 var t string
220
221 var digits uint64
222 var kind reflect.Kind
223
224 if idx := strings.Index(fe.Param(), "."); idx != -1 {
225 digits = uint64(len(fe.Param()[idx+1:]))
226 }
227
228 f64, err := strconv.ParseFloat(fe.Param(), 64)
229 if err != nil {
230 goto END
231 }
232
233 kind = fe.Kind()
234 if kind == reflect.Ptr {
235 kind = fe.Type().Elem().Kind()
236 }
237
238 switch kind {
239 case reflect.String:
240
241 var c string
242
243 c, err = ut.C("min-string-character", f64, digits, ut.FmtNumber(f64, digits))
244 if err != nil {
245 goto END
246 }
247
248 t, err = ut.T("min-string", fe.Field(), c)
249
250 case reflect.Slice, reflect.Map, reflect.Array:
251 var c string
252
253 c, err = ut.C("min-items-item", f64, digits, ut.FmtNumber(f64, digits))
254 if err != nil {
255 goto END
256 }
257
258 t, err = ut.T("min-items", fe.Field(), c)
259
260 default:
261 t, err = ut.T("min-number", fe.Field(), ut.FmtNumber(f64, digits))
262 }
263
264 END:
265 if err != nil {
266 fmt.Printf("warning: error translating FieldError: %s", err)
267 return fe.(error).Error()
268 }
269
270 return t
271 },
272 },
273 {
274 tag: "max",
275 customRegisFunc: func(ut ut.Translator) (err error) {
276 if err = ut.Add("max-string", "{0} must be a maximum of {1} in length", false); err != nil {
277 return
278 }
279
280 if err = ut.AddCardinal("max-string-character", "{0} character", locales.PluralRuleOne, false); err != nil {
281 return
282 }
283
284 if err = ut.AddCardinal("max-string-character", "{0} characters", locales.PluralRuleOther, false); err != nil {
285 return
286 }
287
288 if err = ut.Add("max-number", "{0} must be {1} or less", false); err != nil {
289 return
290 }
291
292 if err = ut.Add("max-items", "{0} must contain at maximum {1}", false); err != nil {
293 return
294 }
295 if err = ut.AddCardinal("max-items-item", "{0} item", locales.PluralRuleOne, false); err != nil {
296 return
297 }
298
299 if err = ut.AddCardinal("max-items-item", "{0} items", locales.PluralRuleOther, false); err != nil {
300 return
301 }
302
303 return
304 },
305 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
306 var err error
307 var t string
308
309 var digits uint64
310 var kind reflect.Kind
311
312 if idx := strings.Index(fe.Param(), "."); idx != -1 {
313 digits = uint64(len(fe.Param()[idx+1:]))
314 }
315
316 f64, err := strconv.ParseFloat(fe.Param(), 64)
317 if err != nil {
318 goto END
319 }
320
321 kind = fe.Kind()
322 if kind == reflect.Ptr {
323 kind = fe.Type().Elem().Kind()
324 }
325
326 switch kind {
327 case reflect.String:
328
329 var c string
330
331 c, err = ut.C("max-string-character", f64, digits, ut.FmtNumber(f64, digits))
332 if err != nil {
333 goto END
334 }
335
336 t, err = ut.T("max-string", fe.Field(), c)
337
338 case reflect.Slice, reflect.Map, reflect.Array:
339 var c string
340
341 c, err = ut.C("max-items-item", f64, digits, ut.FmtNumber(f64, digits))
342 if err != nil {
343 goto END
344 }
345
346 t, err = ut.T("max-items", fe.Field(), c)
347
348 default:
349 t, err = ut.T("max-number", fe.Field(), ut.FmtNumber(f64, digits))
350 }
351
352 END:
353 if err != nil {
354 fmt.Printf("warning: error translating FieldError: %s", err)
355 return fe.(error).Error()
356 }
357
358 return t
359 },
360 },
361 {
362 tag: "eq",
363 translation: "{0} is not equal to {1}",
364 override: false,
365 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
366 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
367 if err != nil {
368 fmt.Printf("warning: error translating FieldError: %#v", fe)
369 return fe.(error).Error()
370 }
371
372 return t
373 },
374 },
375 {
376 tag: "ne",
377 translation: "{0} should not be equal to {1}",
378 override: false,
379 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
380 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
381 if err != nil {
382 fmt.Printf("warning: error translating FieldError: %#v", fe)
383 return fe.(error).Error()
384 }
385
386 return t
387 },
388 },
389 {
390 tag: "lt",
391 customRegisFunc: func(ut ut.Translator) (err error) {
392 if err = ut.Add("lt-string", "{0} must be less than {1} in length", false); err != nil {
393 return
394 }
395
396 if err = ut.AddCardinal("lt-string-character", "{0} character", locales.PluralRuleOne, false); err != nil {
397 return
398 }
399
400 if err = ut.AddCardinal("lt-string-character", "{0} characters", locales.PluralRuleOther, false); err != nil {
401 return
402 }
403
404 if err = ut.Add("lt-number", "{0} must be less than {1}", false); err != nil {
405 return
406 }
407
408 if err = ut.Add("lt-items", "{0} must contain less than {1}", false); err != nil {
409 return
410 }
411
412 if err = ut.AddCardinal("lt-items-item", "{0} item", locales.PluralRuleOne, false); err != nil {
413 return
414 }
415
416 if err = ut.AddCardinal("lt-items-item", "{0} items", locales.PluralRuleOther, false); err != nil {
417 return
418 }
419
420 if err = ut.Add("lt-datetime", "{0} must be less than the current Date & Time", false); err != nil {
421 return
422 }
423
424 return
425 },
426 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
427 var err error
428 var t string
429 var f64 float64
430 var digits uint64
431 var kind reflect.Kind
432
433 fn := func() (err error) {
434 if idx := strings.Index(fe.Param(), "."); idx != -1 {
435 digits = uint64(len(fe.Param()[idx+1:]))
436 }
437
438 f64, err = strconv.ParseFloat(fe.Param(), 64)
439
440 return
441 }
442
443 kind = fe.Kind()
444 if kind == reflect.Ptr {
445 kind = fe.Type().Elem().Kind()
446 }
447
448 switch kind {
449 case reflect.String:
450
451 var c string
452
453 err = fn()
454 if err != nil {
455 goto END
456 }
457
458 c, err = ut.C("lt-string-character", f64, digits, ut.FmtNumber(f64, digits))
459 if err != nil {
460 goto END
461 }
462
463 t, err = ut.T("lt-string", fe.Field(), c)
464
465 case reflect.Slice, reflect.Map, reflect.Array:
466 var c string
467
468 err = fn()
469 if err != nil {
470 goto END
471 }
472
473 c, err = ut.C("lt-items-item", f64, digits, ut.FmtNumber(f64, digits))
474 if err != nil {
475 goto END
476 }
477
478 t, err = ut.T("lt-items", fe.Field(), c)
479
480 case reflect.Struct:
481 if fe.Type() != reflect.TypeOf(time.Time{}) {
482 err = fmt.Errorf("tag '%s' cannot be used on a struct type", fe.Tag())
483 goto END
484 }
485
486 t, err = ut.T("lt-datetime", fe.Field())
487
488 default:
489 err = fn()
490 if err != nil {
491 goto END
492 }
493
494 t, err = ut.T("lt-number", fe.Field(), ut.FmtNumber(f64, digits))
495 }
496
497 END:
498 if err != nil {
499 fmt.Printf("warning: error translating FieldError: %s", err)
500 return fe.(error).Error()
501 }
502
503 return t
504 },
505 },
506 {
507 tag: "lte",
508 customRegisFunc: func(ut ut.Translator) (err error) {
509 if err = ut.Add("lte-string", "{0} must be at maximum {1} in length", false); err != nil {
510 return
511 }
512
513 if err = ut.AddCardinal("lte-string-character", "{0} character", locales.PluralRuleOne, false); err != nil {
514 return
515 }
516
517 if err = ut.AddCardinal("lte-string-character", "{0} characters", locales.PluralRuleOther, false); err != nil {
518 return
519 }
520
521 if err = ut.Add("lte-number", "{0} must be {1} or less", false); err != nil {
522 return
523 }
524
525 if err = ut.Add("lte-items", "{0} must contain at maximum {1}", false); err != nil {
526 return
527 }
528
529 if err = ut.AddCardinal("lte-items-item", "{0} item", locales.PluralRuleOne, false); err != nil {
530 return
531 }
532
533 if err = ut.AddCardinal("lte-items-item", "{0} items", locales.PluralRuleOther, false); err != nil {
534 return
535 }
536
537 if err = ut.Add("lte-datetime", "{0} must be less than or equal to the current Date & Time", false); err != nil {
538 return
539 }
540
541 return
542 },
543 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
544 var err error
545 var t string
546 var f64 float64
547 var digits uint64
548 var kind reflect.Kind
549
550 fn := func() (err error) {
551 if idx := strings.Index(fe.Param(), "."); idx != -1 {
552 digits = uint64(len(fe.Param()[idx+1:]))
553 }
554
555 f64, err = strconv.ParseFloat(fe.Param(), 64)
556
557 return
558 }
559
560 kind = fe.Kind()
561 if kind == reflect.Ptr {
562 kind = fe.Type().Elem().Kind()
563 }
564
565 switch kind {
566 case reflect.String:
567
568 var c string
569
570 err = fn()
571 if err != nil {
572 goto END
573 }
574
575 c, err = ut.C("lte-string-character", f64, digits, ut.FmtNumber(f64, digits))
576 if err != nil {
577 goto END
578 }
579
580 t, err = ut.T("lte-string", fe.Field(), c)
581
582 case reflect.Slice, reflect.Map, reflect.Array:
583 var c string
584
585 err = fn()
586 if err != nil {
587 goto END
588 }
589
590 c, err = ut.C("lte-items-item", f64, digits, ut.FmtNumber(f64, digits))
591 if err != nil {
592 goto END
593 }
594
595 t, err = ut.T("lte-items", fe.Field(), c)
596
597 case reflect.Struct:
598 if fe.Type() != reflect.TypeOf(time.Time{}) {
599 err = fmt.Errorf("tag '%s' cannot be used on a struct type", fe.Tag())
600 goto END
601 }
602
603 t, err = ut.T("lte-datetime", fe.Field())
604
605 default:
606 err = fn()
607 if err != nil {
608 goto END
609 }
610
611 t, err = ut.T("lte-number", fe.Field(), ut.FmtNumber(f64, digits))
612 }
613
614 END:
615 if err != nil {
616 fmt.Printf("warning: error translating FieldError: %s", err)
617 return fe.(error).Error()
618 }
619
620 return t
621 },
622 },
623 {
624 tag: "gt",
625 customRegisFunc: func(ut ut.Translator) (err error) {
626 if err = ut.Add("gt-string", "{0} must be greater than {1} in length", false); err != nil {
627 return
628 }
629
630 if err = ut.AddCardinal("gt-string-character", "{0} character", locales.PluralRuleOne, false); err != nil {
631 return
632 }
633
634 if err = ut.AddCardinal("gt-string-character", "{0} characters", locales.PluralRuleOther, false); err != nil {
635 return
636 }
637
638 if err = ut.Add("gt-number", "{0} must be greater than {1}", false); err != nil {
639 return
640 }
641
642 if err = ut.Add("gt-items", "{0} must contain more than {1}", false); err != nil {
643 return
644 }
645
646 if err = ut.AddCardinal("gt-items-item", "{0} item", locales.PluralRuleOne, false); err != nil {
647 return
648 }
649
650 if err = ut.AddCardinal("gt-items-item", "{0} items", locales.PluralRuleOther, false); err != nil {
651 return
652 }
653
654 if err = ut.Add("gt-datetime", "{0} must be greater than the current Date & Time", false); err != nil {
655 return
656 }
657
658 return
659 },
660 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
661 var err error
662 var t string
663 var f64 float64
664 var digits uint64
665 var kind reflect.Kind
666
667 fn := func() (err error) {
668 if idx := strings.Index(fe.Param(), "."); idx != -1 {
669 digits = uint64(len(fe.Param()[idx+1:]))
670 }
671
672 f64, err = strconv.ParseFloat(fe.Param(), 64)
673
674 return
675 }
676
677 kind = fe.Kind()
678 if kind == reflect.Ptr {
679 kind = fe.Type().Elem().Kind()
680 }
681
682 switch kind {
683 case reflect.String:
684
685 var c string
686
687 err = fn()
688 if err != nil {
689 goto END
690 }
691
692 c, err = ut.C("gt-string-character", f64, digits, ut.FmtNumber(f64, digits))
693 if err != nil {
694 goto END
695 }
696
697 t, err = ut.T("gt-string", fe.Field(), c)
698
699 case reflect.Slice, reflect.Map, reflect.Array:
700 var c string
701
702 err = fn()
703 if err != nil {
704 goto END
705 }
706
707 c, err = ut.C("gt-items-item", f64, digits, ut.FmtNumber(f64, digits))
708 if err != nil {
709 goto END
710 }
711
712 t, err = ut.T("gt-items", fe.Field(), c)
713
714 case reflect.Struct:
715 if fe.Type() != reflect.TypeOf(time.Time{}) {
716 err = fmt.Errorf("tag '%s' cannot be used on a struct type", fe.Tag())
717 goto END
718 }
719
720 t, err = ut.T("gt-datetime", fe.Field())
721
722 default:
723 err = fn()
724 if err != nil {
725 goto END
726 }
727
728 t, err = ut.T("gt-number", fe.Field(), ut.FmtNumber(f64, digits))
729 }
730
731 END:
732 if err != nil {
733 fmt.Printf("warning: error translating FieldError: %s", err)
734 return fe.(error).Error()
735 }
736
737 return t
738 },
739 },
740 {
741 tag: "gte",
742 customRegisFunc: func(ut ut.Translator) (err error) {
743 if err = ut.Add("gte-string", "{0} must be at least {1} in length", false); err != nil {
744 return
745 }
746
747 if err = ut.AddCardinal("gte-string-character", "{0} character", locales.PluralRuleOne, false); err != nil {
748 return
749 }
750
751 if err = ut.AddCardinal("gte-string-character", "{0} characters", locales.PluralRuleOther, false); err != nil {
752 return
753 }
754
755 if err = ut.Add("gte-number", "{0} must be {1} or greater", false); err != nil {
756 return
757 }
758
759 if err = ut.Add("gte-items", "{0} must contain at least {1}", false); err != nil {
760 return
761 }
762
763 if err = ut.AddCardinal("gte-items-item", "{0} item", locales.PluralRuleOne, false); err != nil {
764 return
765 }
766
767 if err = ut.AddCardinal("gte-items-item", "{0} items", locales.PluralRuleOther, false); err != nil {
768 return
769 }
770
771 if err = ut.Add("gte-datetime", "{0} must be greater than or equal to the current Date & Time", false); err != nil {
772 return
773 }
774
775 return
776 },
777 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
778 var err error
779 var t string
780 var f64 float64
781 var digits uint64
782 var kind reflect.Kind
783
784 fn := func() (err error) {
785 if idx := strings.Index(fe.Param(), "."); idx != -1 {
786 digits = uint64(len(fe.Param()[idx+1:]))
787 }
788
789 f64, err = strconv.ParseFloat(fe.Param(), 64)
790
791 return
792 }
793
794 kind = fe.Kind()
795 if kind == reflect.Ptr {
796 kind = fe.Type().Elem().Kind()
797 }
798
799 switch kind {
800 case reflect.String:
801
802 var c string
803
804 err = fn()
805 if err != nil {
806 goto END
807 }
808
809 c, err = ut.C("gte-string-character", f64, digits, ut.FmtNumber(f64, digits))
810 if err != nil {
811 goto END
812 }
813
814 t, err = ut.T("gte-string", fe.Field(), c)
815
816 case reflect.Slice, reflect.Map, reflect.Array:
817 var c string
818
819 err = fn()
820 if err != nil {
821 goto END
822 }
823
824 c, err = ut.C("gte-items-item", f64, digits, ut.FmtNumber(f64, digits))
825 if err != nil {
826 goto END
827 }
828
829 t, err = ut.T("gte-items", fe.Field(), c)
830
831 case reflect.Struct:
832 if fe.Type() != reflect.TypeOf(time.Time{}) {
833 err = fmt.Errorf("tag '%s' cannot be used on a struct type", fe.Tag())
834 goto END
835 }
836
837 t, err = ut.T("gte-datetime", fe.Field())
838
839 default:
840 err = fn()
841 if err != nil {
842 goto END
843 }
844
845 t, err = ut.T("gte-number", fe.Field(), ut.FmtNumber(f64, digits))
846 }
847
848 END:
849 if err != nil {
850 fmt.Printf("warning: error translating FieldError: %s", err)
851 return fe.(error).Error()
852 }
853
854 return t
855 },
856 },
857 {
858 tag: "eqfield",
859 translation: "{0} must be equal to {1}",
860 override: false,
861 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
862 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
863 if err != nil {
864 log.Printf("warning: error translating FieldError: %#v", fe)
865 return fe.(error).Error()
866 }
867
868 return t
869 },
870 },
871 {
872 tag: "eqcsfield",
873 translation: "{0} must be equal to {1}",
874 override: false,
875 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
876 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
877 if err != nil {
878 log.Printf("warning: error translating FieldError: %#v", fe)
879 return fe.(error).Error()
880 }
881
882 return t
883 },
884 },
885 {
886 tag: "necsfield",
887 translation: "{0} cannot be equal to {1}",
888 override: false,
889 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
890 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
891 if err != nil {
892 log.Printf("warning: error translating FieldError: %#v", fe)
893 return fe.(error).Error()
894 }
895
896 return t
897 },
898 },
899 {
900 tag: "gtcsfield",
901 translation: "{0} must be greater than {1}",
902 override: false,
903 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
904 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
905 if err != nil {
906 log.Printf("warning: error translating FieldError: %#v", fe)
907 return fe.(error).Error()
908 }
909
910 return t
911 },
912 },
913 {
914 tag: "gtecsfield",
915 translation: "{0} must be greater than or equal to {1}",
916 override: false,
917 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
918 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
919 if err != nil {
920 log.Printf("warning: error translating FieldError: %#v", fe)
921 return fe.(error).Error()
922 }
923
924 return t
925 },
926 },
927 {
928 tag: "ltcsfield",
929 translation: "{0} must be less than {1}",
930 override: false,
931 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
932 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
933 if err != nil {
934 log.Printf("warning: error translating FieldError: %#v", fe)
935 return fe.(error).Error()
936 }
937
938 return t
939 },
940 },
941 {
942 tag: "ltecsfield",
943 translation: "{0} must be less than or equal to {1}",
944 override: false,
945 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
946 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
947 if err != nil {
948 log.Printf("warning: error translating FieldError: %#v", fe)
949 return fe.(error).Error()
950 }
951
952 return t
953 },
954 },
955 {
956 tag: "nefield",
957 translation: "{0} cannot be equal to {1}",
958 override: false,
959 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
960 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
961 if err != nil {
962 log.Printf("warning: error translating FieldError: %#v", fe)
963 return fe.(error).Error()
964 }
965
966 return t
967 },
968 },
969 {
970 tag: "gtfield",
971 translation: "{0} must be greater than {1}",
972 override: false,
973 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
974 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
975 if err != nil {
976 log.Printf("warning: error translating FieldError: %#v", fe)
977 return fe.(error).Error()
978 }
979
980 return t
981 },
982 },
983 {
984 tag: "gtefield",
985 translation: "{0} must be greater than or equal to {1}",
986 override: false,
987 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
988 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
989 if err != nil {
990 log.Printf("warning: error translating FieldError: %#v", fe)
991 return fe.(error).Error()
992 }
993
994 return t
995 },
996 },
997 {
998 tag: "ltfield",
999 translation: "{0} must be less than {1}",
1000 override: false,
1001 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1002 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
1003 if err != nil {
1004 log.Printf("warning: error translating FieldError: %#v", fe)
1005 return fe.(error).Error()
1006 }
1007
1008 return t
1009 },
1010 },
1011 {
1012 tag: "ltefield",
1013 translation: "{0} must be less than or equal to {1}",
1014 override: false,
1015 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1016 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
1017 if err != nil {
1018 log.Printf("warning: error translating FieldError: %#v", fe)
1019 return fe.(error).Error()
1020 }
1021
1022 return t
1023 },
1024 },
1025 {
1026 tag: "alpha",
1027 translation: "{0} can only contain alphabetic characters",
1028 override: false,
1029 },
1030 {
1031 tag: "alphanum",
1032 translation: "{0} can only contain alphanumeric characters",
1033 override: false,
1034 },
1035 {
1036 tag: "numeric",
1037 translation: "{0} must be a valid numeric value",
1038 override: false,
1039 },
1040 {
1041 tag: "number",
1042 translation: "{0} must be a valid number",
1043 override: false,
1044 },
1045 {
1046 tag: "hexadecimal",
1047 translation: "{0} must be a valid hexadecimal",
1048 override: false,
1049 },
1050 {
1051 tag: "hexcolor",
1052 translation: "{0} must be a valid HEX color",
1053 override: false,
1054 },
1055 {
1056 tag: "rgb",
1057 translation: "{0} must be a valid RGB color",
1058 override: false,
1059 },
1060 {
1061 tag: "rgba",
1062 translation: "{0} must be a valid RGBA color",
1063 override: false,
1064 },
1065 {
1066 tag: "hsl",
1067 translation: "{0} must be a valid HSL color",
1068 override: false,
1069 },
1070 {
1071 tag: "hsla",
1072 translation: "{0} must be a valid HSLA color",
1073 override: false,
1074 },
1075 {
1076 tag: "e164",
1077 translation: "{0} must be a valid E.164 formatted phone number",
1078 override: false,
1079 },
1080 {
1081 tag: "email",
1082 translation: "{0} must be a valid email address",
1083 override: false,
1084 },
1085 {
1086 tag: "url",
1087 translation: "{0} must be a valid URL",
1088 override: false,
1089 },
1090 {
1091 tag: "uri",
1092 translation: "{0} must be a valid URI",
1093 override: false,
1094 },
1095 {
1096 tag: "base64",
1097 translation: "{0} must be a valid Base64 string",
1098 override: false,
1099 },
1100 {
1101 tag: "contains",
1102 translation: "{0} must contain the text '{1}'",
1103 override: false,
1104 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1105 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
1106 if err != nil {
1107 log.Printf("warning: error translating FieldError: %#v", fe)
1108 return fe.(error).Error()
1109 }
1110
1111 return t
1112 },
1113 },
1114 {
1115 tag: "containsany",
1116 translation: "{0} must contain at least one of the following characters '{1}'",
1117 override: false,
1118 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1119 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
1120 if err != nil {
1121 log.Printf("warning: error translating FieldError: %#v", fe)
1122 return fe.(error).Error()
1123 }
1124
1125 return t
1126 },
1127 },
1128 {
1129 tag: "excludes",
1130 translation: "{0} cannot contain the text '{1}'",
1131 override: false,
1132 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1133 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
1134 if err != nil {
1135 log.Printf("warning: error translating FieldError: %#v", fe)
1136 return fe.(error).Error()
1137 }
1138
1139 return t
1140 },
1141 },
1142 {
1143 tag: "excludesall",
1144 translation: "{0} cannot contain any of the following characters '{1}'",
1145 override: false,
1146 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1147 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
1148 if err != nil {
1149 log.Printf("warning: error translating FieldError: %#v", fe)
1150 return fe.(error).Error()
1151 }
1152
1153 return t
1154 },
1155 },
1156 {
1157 tag: "excludesrune",
1158 translation: "{0} cannot contain the following '{1}'",
1159 override: false,
1160 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1161 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
1162 if err != nil {
1163 log.Printf("warning: error translating FieldError: %#v", fe)
1164 return fe.(error).Error()
1165 }
1166
1167 return t
1168 },
1169 },
1170 {
1171 tag: "isbn",
1172 translation: "{0} must be a valid ISBN number",
1173 override: false,
1174 },
1175 {
1176 tag: "isbn10",
1177 translation: "{0} must be a valid ISBN-10 number",
1178 override: false,
1179 },
1180 {
1181 tag: "isbn13",
1182 translation: "{0} must be a valid ISBN-13 number",
1183 override: false,
1184 },
1185 {
1186 tag: "issn",
1187 translation: "{0} must be a valid ISSN number",
1188 override: false,
1189 },
1190 {
1191 tag: "uuid",
1192 translation: "{0} must be a valid UUID",
1193 override: false,
1194 },
1195 {
1196 tag: "uuid3",
1197 translation: "{0} must be a valid version 3 UUID",
1198 override: false,
1199 },
1200 {
1201 tag: "uuid4",
1202 translation: "{0} must be a valid version 4 UUID",
1203 override: false,
1204 },
1205 {
1206 tag: "uuid5",
1207 translation: "{0} must be a valid version 5 UUID",
1208 override: false,
1209 },
1210 {
1211 tag: "ulid",
1212 translation: "{0} must be a valid ULID",
1213 override: false,
1214 },
1215 {
1216 tag: "ascii",
1217 translation: "{0} must contain only ascii characters",
1218 override: false,
1219 },
1220 {
1221 tag: "printascii",
1222 translation: "{0} must contain only printable ascii characters",
1223 override: false,
1224 },
1225 {
1226 tag: "multibyte",
1227 translation: "{0} must contain multibyte characters",
1228 override: false,
1229 },
1230 {
1231 tag: "datauri",
1232 translation: "{0} must contain a valid Data URI",
1233 override: false,
1234 },
1235 {
1236 tag: "latitude",
1237 translation: "{0} must contain valid latitude coordinates",
1238 override: false,
1239 },
1240 {
1241 tag: "longitude",
1242 translation: "{0} must contain a valid longitude coordinates",
1243 override: false,
1244 },
1245 {
1246 tag: "ssn",
1247 translation: "{0} must be a valid SSN number",
1248 override: false,
1249 },
1250 {
1251 tag: "ipv4",
1252 translation: "{0} must be a valid IPv4 address",
1253 override: false,
1254 },
1255 {
1256 tag: "ipv6",
1257 translation: "{0} must be a valid IPv6 address",
1258 override: false,
1259 },
1260 {
1261 tag: "ip",
1262 translation: "{0} must be a valid IP address",
1263 override: false,
1264 },
1265 {
1266 tag: "cidr",
1267 translation: "{0} must contain a valid CIDR notation",
1268 override: false,
1269 },
1270 {
1271 tag: "cidrv4",
1272 translation: "{0} must contain a valid CIDR notation for an IPv4 address",
1273 override: false,
1274 },
1275 {
1276 tag: "cidrv6",
1277 translation: "{0} must contain a valid CIDR notation for an IPv6 address",
1278 override: false,
1279 },
1280 {
1281 tag: "tcp_addr",
1282 translation: "{0} must be a valid TCP address",
1283 override: false,
1284 },
1285 {
1286 tag: "tcp4_addr",
1287 translation: "{0} must be a valid IPv4 TCP address",
1288 override: false,
1289 },
1290 {
1291 tag: "tcp6_addr",
1292 translation: "{0} must be a valid IPv6 TCP address",
1293 override: false,
1294 },
1295 {
1296 tag: "udp_addr",
1297 translation: "{0} must be a valid UDP address",
1298 override: false,
1299 },
1300 {
1301 tag: "udp4_addr",
1302 translation: "{0} must be a valid IPv4 UDP address",
1303 override: false,
1304 },
1305 {
1306 tag: "udp6_addr",
1307 translation: "{0} must be a valid IPv6 UDP address",
1308 override: false,
1309 },
1310 {
1311 tag: "ip_addr",
1312 translation: "{0} must be a resolvable IP address",
1313 override: false,
1314 },
1315 {
1316 tag: "ip4_addr",
1317 translation: "{0} must be a resolvable IPv4 address",
1318 override: false,
1319 },
1320 {
1321 tag: "ip6_addr",
1322 translation: "{0} must be a resolvable IPv6 address",
1323 override: false,
1324 },
1325 {
1326 tag: "unix_addr",
1327 translation: "{0} must be a resolvable UNIX address",
1328 override: false,
1329 },
1330 {
1331 tag: "mac",
1332 translation: "{0} must contain a valid MAC address",
1333 override: false,
1334 },
1335 {
1336 tag: "fqdn",
1337 translation: "{0} must be a valid FQDN",
1338 override: false,
1339 },
1340 {
1341 tag: "unique",
1342 translation: "{0} must contain unique values",
1343 override: false,
1344 },
1345 {
1346 tag: "iscolor",
1347 translation: "{0} must be a valid color",
1348 override: false,
1349 },
1350 {
1351 tag: "cron",
1352 translation: "{0} must be a valid cron expression",
1353 override: false,
1354 },
1355 {
1356 tag: "oneof",
1357 translation: "{0} must be one of [{1}]",
1358 override: false,
1359 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1360 s, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
1361 if err != nil {
1362 log.Printf("warning: error translating FieldError: %#v", fe)
1363 return fe.(error).Error()
1364 }
1365 return s
1366 },
1367 },
1368 {
1369 tag: "json",
1370 translation: "{0} must be a valid json string",
1371 override: false,
1372 },
1373 {
1374 tag: "jwt",
1375 translation: "{0} must be a valid jwt string",
1376 override: false,
1377 },
1378 {
1379 tag: "lowercase",
1380 translation: "{0} must be a lowercase string",
1381 override: false,
1382 },
1383 {
1384 tag: "uppercase",
1385 translation: "{0} must be an uppercase string",
1386 override: false,
1387 },
1388 {
1389 tag: "datetime",
1390 translation: "{0} does not match the {1} format",
1391 override: false,
1392 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1393 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
1394 if err != nil {
1395 log.Printf("warning: error translating FieldError: %#v", fe)
1396 return fe.(error).Error()
1397 }
1398
1399 return t
1400 },
1401 },
1402 {
1403 tag: "postcode_iso3166_alpha2",
1404 translation: "{0} does not match postcode format of {1} country",
1405 override: false,
1406 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1407 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
1408 if err != nil {
1409 log.Printf("warning: error translating FieldError: %#v", fe)
1410 return fe.(error).Error()
1411 }
1412
1413 return t
1414 },
1415 },
1416 {
1417 tag: "postcode_iso3166_alpha2_field",
1418 translation: "{0} does not match postcode format of country in {1} field",
1419 override: false,
1420 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1421 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
1422 if err != nil {
1423 log.Printf("warning: error translating FieldError: %#v", fe)
1424 return fe.(error).Error()
1425 }
1426
1427 return t
1428 },
1429 },
1430 {
1431 tag: "boolean",
1432 translation: "{0} must be a valid boolean value",
1433 override: false,
1434 },
1435 {
1436 tag: "image",
1437 translation: "{0} must be a valid image",
1438 override: false,
1439 },
1440 {
1441 tag: "cve",
1442 translation: "{0} must be a valid cve identifier",
1443 override: false,
1444 },
1445 }
1446
1447 for _, t := range translations {
1448
1449 if t.customTransFunc != nil && t.customRegisFunc != nil {
1450 err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, t.customTransFunc)
1451 } else if t.customTransFunc != nil && t.customRegisFunc == nil {
1452 err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), t.customTransFunc)
1453 } else if t.customTransFunc == nil && t.customRegisFunc != nil {
1454 err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, translateFunc)
1455 } else {
1456 err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), translateFunc)
1457 }
1458
1459 if err != nil {
1460 return
1461 }
1462 }
1463
1464 return
1465 }
1466
1467 func registrationFunc(tag string, translation string, override bool) validator.RegisterTranslationsFunc {
1468 return func(ut ut.Translator) (err error) {
1469 if err = ut.Add(tag, translation, override); err != nil {
1470 return
1471 }
1472
1473 return
1474 }
1475 }
1476
1477 func translateFunc(ut ut.Translator, fe validator.FieldError) string {
1478 t, err := ut.T(fe.Tag(), fe.Field())
1479 if err != nil {
1480 log.Printf("warning: error translating FieldError: %#v", fe)
1481 return fe.(error).Error()
1482 }
1483
1484 return t
1485 }
1486
View as plain text