-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathvalidator.go
136 lines (108 loc) · 3.43 KB
/
validator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package webfmwk
import (
"errors"
"fmt"
"reflect"
"strings"
en_translator "github.com/go-playground/locales/en"
ut "github.com/go-playground/universal-translator"
validator "github.com/go-playground/validator/v10"
en_translations "github.com/go-playground/validator/v10/translations/en"
)
type (
// ValidationError is returned in case of form / query validation error
// see gtihub.com/go-playground/validator.v10
ValidationError struct {
Error ErrorValidation `json:"message"`
Status int `json:"status"`
}
// ErrorsValidation is a map of translated errors
ErrorValidation map[string]string
)
var (
// validate annotation : `validate` : go-playground
validate *validator.Validate
// universal translator
uni *ut.UniversalTranslator
// this is usually know or extracted from http 'Accept-Language' header
// also see uni.FindTranslator(...)
trans ut.Translator
)
var ErrGetTranslator = errors.New("fetching the 'en' translator")
func initValidator() error {
var (
en = en_translator.New()
ok bool
)
uni = ut.New(en, en)
if trans, ok = uni.GetTranslator("en"); !ok {
return ErrGetTranslator
}
validate = validator.New()
if e := en_translations.RegisterDefaultTranslations(validate, trans); e != nil {
return fmt.Errorf("initializing the 'en' translator : %w", e)
}
useJSONFieldName()
return nil
}
// Trnaslate the errs array of validation error and use the actual filed name
// instad of the full struct namepsace one.
// src: https://blog.depa.do/post/gin-validation-errors-handling#toc_8
func TranslateAndUseFieldName(errs validator.ValidationErrors) ErrorValidation {
es := ErrorValidation{}
for _, f := range errs {
es[f.Field()] = f.Translate(trans)
}
return es
}
// Use the struct json field name for validation errors
// src: shorturl.at/evDJ0
func useJSONFieldName() {
validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
//nolint: gomnd
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
if name == "-" {
return ""
}
return name
})
}
// RegisterValidatorRule register the validation rule param.
// See https://go-playground/validator.v10 for more.
func RegisterValidatorRule(name string, fn func(fl validator.FieldLevel) bool) (e error) {
once.Do(func() { e = initOnce() })
if e != nil {
return fmt.Errorf("registering validator rule: %w", e)
}
return validate.RegisterValidation(name, fn)
}
// RegisterValidatorAlias register some validation alias.
// See https://go-playground/validator.v10 for more.
func RegisterValidatorAlias(name, what string) (e error) {
// from init server - if validator is called before
// the server init (which may happen pretty often)
once.Do(func() { e = initOnce() })
if e != nil {
return fmt.Errorf("registering validator alias: %w", e)
}
validate.RegisterAlias(name, what)
return nil
}
// RegisterValidatorTrans register some validation alias.
// See https://go-playground/validator.v10 for more.
func RegisterValidatorTrans(name, what string) (e error) {
// from init server - if validator is called before
// the server init (which may happen pretty often)
once.Do(func() { e = initOnce() })
if e != nil {
return fmt.Errorf("init validator: %w", e)
}
return validate.RegisterTranslation(name, trans,
func(ut ut.Translator) error {
return ut.Add(name, what, true) // see universal-translator for details
},
func(ut ut.Translator, fe validator.FieldError) string {
t, _ := ut.T(name, fe.Field())
return t
})
}