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