OSDN Git Service

new repo
[bytom/vapor.git] / vendor / gopkg.in / go-playground / validator.v9 / errors.go
1 package validator
2
3 import (
4         "bytes"
5         "fmt"
6         "reflect"
7         "strings"
8
9         ut "github.com/go-playground/universal-translator"
10 )
11
12 const (
13         fieldErrMsg = "Key: '%s' Error:Field validation for '%s' failed on the '%s' tag"
14 )
15
16 // ValidationErrorsTranslations is the translation return type
17 type ValidationErrorsTranslations map[string]string
18
19 // InvalidValidationError describes an invalid argument passed to
20 // `Struct`, `StructExcept`, StructPartial` or `Field`
21 type InvalidValidationError struct {
22         Type reflect.Type
23 }
24
25 // Error returns InvalidValidationError message
26 func (e *InvalidValidationError) Error() string {
27
28         if e.Type == nil {
29                 return "validator: (nil)"
30         }
31
32         return "validator: (nil " + e.Type.String() + ")"
33 }
34
35 // ValidationErrors is an array of FieldError's
36 // for use in custom error messages post validation.
37 type ValidationErrors []FieldError
38
39 // Error is intended for use in development + debugging and not intended to be a production error message.
40 // It allows ValidationErrors to subscribe to the Error interface.
41 // All information to create an error message specific to your application is contained within
42 // the FieldError found within the ValidationErrors array
43 func (ve ValidationErrors) Error() string {
44
45         buff := bytes.NewBufferString("")
46
47         var fe *fieldError
48
49         for i := 0; i < len(ve); i++ {
50
51                 fe = ve[i].(*fieldError)
52                 buff.WriteString(fe.Error())
53                 buff.WriteString("\n")
54         }
55
56         return strings.TrimSpace(buff.String())
57 }
58
59 // Translate translates all of the ValidationErrors
60 func (ve ValidationErrors) Translate(ut ut.Translator) ValidationErrorsTranslations {
61
62         trans := make(ValidationErrorsTranslations)
63
64         var fe *fieldError
65
66         for i := 0; i < len(ve); i++ {
67                 fe = ve[i].(*fieldError)
68
69                 // // in case an Anonymous struct was used, ensure that the key
70                 // // would be 'Username' instead of ".Username"
71                 // if len(fe.ns) > 0 && fe.ns[:1] == "." {
72                 //      trans[fe.ns[1:]] = fe.Translate(ut)
73                 //      continue
74                 // }
75
76                 trans[fe.ns] = fe.Translate(ut)
77         }
78
79         return trans
80 }
81
82 // FieldError contains all functions to get error details
83 type FieldError interface {
84
85         // returns the validation tag that failed. if the
86         // validation was an alias, this will return the
87         // alias name and not the underlying tag that failed.
88         //
89         // eg. alias "iscolor": "hexcolor|rgb|rgba|hsl|hsla"
90         // will return "iscolor"
91         Tag() string
92
93         // returns the validation tag that failed, even if an
94         // alias the actual tag within the alias will be returned.
95         // If an 'or' validation fails the entire or will be returned.
96         //
97         // eg. alias "iscolor": "hexcolor|rgb|rgba|hsl|hsla"
98         // will return "hexcolor|rgb|rgba|hsl|hsla"
99         ActualTag() string
100
101         // returns the namespace for the field error, with the tag
102         // name taking precedence over the fields actual name.
103         //
104         // eg. JSON name "User.fname"
105         //
106         // See StructNamespace() for a version that returns actual names.
107         //
108         // NOTE: this field can be blank when validating a single primitive field
109         // using validate.Field(...) as there is no way to extract it's name
110         Namespace() string
111
112         // returns the namespace for the field error, with the fields
113         // actual name.
114         //
115         // eq. "User.FirstName" see Namespace for comparison
116         //
117         // NOTE: this field can be blank when validating a single primitive field
118         // using validate.Field(...) as there is no way to extract it's name
119         StructNamespace() string
120
121         // returns the fields name with the tag name taking precedence over the
122         // fields actual name.
123         //
124         // eq. JSON name "fname"
125         // see ActualField for comparison
126         Field() string
127
128         // returns the fields actual name from the struct, when able to determine.
129         //
130         // eq.  "FirstName"
131         // see Field for comparison
132         StructField() string
133
134         // returns the actual fields value in case needed for creating the error
135         // message
136         Value() interface{}
137
138         // returns the param value, in string form for comparison; this will also
139         // help with generating an error message
140         Param() string
141
142         // Kind returns the Field's reflect Kind
143         //
144         // eg. time.Time's kind is a struct
145         Kind() reflect.Kind
146
147         // Type returns the Field's reflect Type
148         //
149         // // eg. time.Time's type is time.Time
150         Type() reflect.Type
151
152         // returns the FieldError's translated error
153         // from the provided 'ut.Translator' and registered 'TranslationFunc'
154         //
155         // NOTE: is not registered translation can be found it returns the same
156         // as calling fe.Error()
157         Translate(ut ut.Translator) string
158 }
159
160 // compile time interface checks
161 var _ FieldError = new(fieldError)
162 var _ error = new(fieldError)
163
164 // fieldError contains a single field's validation error along
165 // with other properties that may be needed for error message creation
166 // it complies with the FieldError interface
167 type fieldError struct {
168         v              *Validate
169         tag            string
170         actualTag      string
171         ns             string
172         structNs       string
173         fieldLen       uint8
174         structfieldLen uint8
175         value          interface{}
176         param          string
177         kind           reflect.Kind
178         typ            reflect.Type
179 }
180
181 // Tag returns the validation tag that failed.
182 func (fe *fieldError) Tag() string {
183         return fe.tag
184 }
185
186 // ActualTag returns the validation tag that failed, even if an
187 // alias the actual tag within the alias will be returned.
188 func (fe *fieldError) ActualTag() string {
189         return fe.actualTag
190 }
191
192 // Namespace returns the namespace for the field error, with the tag
193 // name taking precedence over the fields actual name.
194 func (fe *fieldError) Namespace() string {
195         return fe.ns
196 }
197
198 // StructNamespace returns the namespace for the field error, with the fields
199 // actual name.
200 func (fe *fieldError) StructNamespace() string {
201         return fe.structNs
202 }
203
204 // Field returns the fields name with the tag name taking precedence over the
205 // fields actual name.
206 func (fe *fieldError) Field() string {
207
208         return fe.ns[len(fe.ns)-int(fe.fieldLen):]
209         // // return fe.field
210         // fld := fe.ns[len(fe.ns)-int(fe.fieldLen):]
211
212         // log.Println("FLD:", fld)
213
214         // if len(fld) > 0 && fld[:1] == "." {
215         //      return fld[1:]
216         // }
217
218         // return fld
219 }
220
221 // returns the fields actual name from the struct, when able to determine.
222 func (fe *fieldError) StructField() string {
223         // return fe.structField
224         return fe.structNs[len(fe.structNs)-int(fe.structfieldLen):]
225 }
226
227 // Value returns the actual fields value in case needed for creating the error
228 // message
229 func (fe *fieldError) Value() interface{} {
230         return fe.value
231 }
232
233 // Param returns the param value, in string form for comparison; this will
234 // also help with generating an error message
235 func (fe *fieldError) Param() string {
236         return fe.param
237 }
238
239 // Kind returns the Field's reflect Kind
240 func (fe *fieldError) Kind() reflect.Kind {
241         return fe.kind
242 }
243
244 // Type returns the Field's reflect Type
245 func (fe *fieldError) Type() reflect.Type {
246         return fe.typ
247 }
248
249 // Error returns the fieldError's error message
250 func (fe *fieldError) Error() string {
251         return fmt.Sprintf(fieldErrMsg, fe.ns, fe.Field(), fe.tag)
252 }
253
254 // Translate returns the FieldError's translated error
255 // from the provided 'ut.Translator' and registered 'TranslationFunc'
256 //
257 // NOTE: is not registered translation can be found it returns the same
258 // as calling fe.Error()
259 func (fe *fieldError) Translate(ut ut.Translator) string {
260
261         m, ok := fe.v.transTagFunc[ut]
262         if !ok {
263                 return fe.Error()
264         }
265
266         fn, ok := m[fe.tag]
267         if !ok {
268                 return fe.Error()
269         }
270
271         return fn(ut, fe)
272 }