-
Notifications
You must be signed in to change notification settings - Fork 0
/
validator.go
147 lines (127 loc) · 2.96 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
137
138
139
140
141
142
143
144
145
146
147
package std
import (
"bytes"
"fmt"
"github.com/go-playground/locales/en"
"github.com/go-playground/locales/zh"
"github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
zhTranslations "github.com/go-playground/validator/v10/translations/zh"
"github.com/pkg/errors"
)
/**
* Created by xuchao on 2019-03-06 .
* Update by suzhen on 2020-08-21 .
*/
// use a single instance , it caches struct info
var (
uni *ut.UniversalTranslator
gValidate *validator.Validate
gValidatorZH = NewValidator(LangZH)
gValidatorEN = NewValidator(LangEN)
)
func GlobalValidator() *validator.Validate {
return gValidate
}
func DefaultValidatorZH() Validator {
return gValidatorZH
}
func DefaultValidatorEN() Validator {
return gValidatorEN
}
type LANG int
const (
LangZH LANG = iota
LangEN
)
const (
StrLangZH = "zh"
StrLangEN = "en"
)
func init() {
zhTranslator := zh.New()
enTranslator := en.New()
uni = ut.New(enTranslator, zhTranslator, enTranslator)
gValidate = validator.New()
trans, found := uni.GetTranslator(StrLangZH)
if found {
if err := zhTranslations.RegisterDefaultTranslations(gValidate, trans); err != nil {
panic(err)
}
}
}
var ValidateUnknownLANG = errors.New("unknown lang")
func (this *LANG) MarshalText() (text []byte, err error) {
switch *this {
case LangZH:
return []byte(StrLangZH), nil
case LangEN:
return []byte(StrLangEN), nil
}
return nil, ValidateUnknownLANG
}
func (this *LANG) UnmarshalText(text []byte) error {
switch string(text) {
case StrLangZH:
*this = LangZH
case StrLangEN:
*this = LangEN
default:
return ValidateUnknownLANG
}
return nil
}
type Validator interface {
Validate(i interface{}) error
}
func ValidateStructWithLanguage(lang LANG, i interface{}) error {
e := gValidate.Struct(i)
if e != nil {
if _, ok := e.(*validator.InvalidValidationError); ok {
return e
}
// translate all error at once
var buffer bytes.Buffer
rawErrs := e.(validator.ValidationErrors)
locale, err := lang.MarshalText()
if err != nil {
return err
}
trans, found := uni.GetTranslator(string(locale))
if found {
tansErrs := rawErrs.Translate(trans)
for _, err := range tansErrs {
buffer.WriteString(fmt.Sprintf("%s;", err))
}
} else {
for _, err := range rawErrs {
eStr := fmt.Sprintf("param:'%s' type:'%s' miss match with check:'%s';",
err.Field(),
err.Kind(),
err.Tag())
buffer.WriteString(eStr)
}
}
return errors.New(buffer.String())
}
return nil
}
// @see ValidateStructWithLanguage LangEN
func ValidateStruct(i interface{}) error {
return ValidateStructWithLanguage(LangEN, i)
}
// @see ValidateStructWithLanguage LangEN
func Verify(i interface{}) error {
return ValidateStructWithLanguage(LangEN, i)
}
type __validator struct {
lang LANG
}
func NewValidator(lang LANG) Validator {
return &__validator{
lang: lang,
}
}
func (this *__validator) Validate(i interface{}) error {
return ValidateStructWithLanguage(this.lang, i)
}