9 ut "github.com/go-playground/universal-translator"
13 fieldErrMsg = "Key: '%s' Error:Field validation for '%s' failed on the '%s' tag"
16 // ValidationErrorsTranslations is the translation return type
17 type ValidationErrorsTranslations map[string]string
19 // InvalidValidationError describes an invalid argument passed to
20 // `Struct`, `StructExcept`, StructPartial` or `Field`
21 type InvalidValidationError struct {
25 // Error returns InvalidValidationError message
26 func (e *InvalidValidationError) Error() string {
29 return "validator: (nil)"
32 return "validator: (nil " + e.Type.String() + ")"
35 // ValidationErrors is an array of FieldError's
36 // for use in custom error messages post validation.
37 type ValidationErrors []FieldError
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 {
45 buff := bytes.NewBufferString("")
49 for i := 0; i < len(ve); i++ {
51 fe = ve[i].(*fieldError)
52 buff.WriteString(fe.Error())
53 buff.WriteString("\n")
56 return strings.TrimSpace(buff.String())
59 // Translate translates all of the ValidationErrors
60 func (ve ValidationErrors) Translate(ut ut.Translator) ValidationErrorsTranslations {
62 trans := make(ValidationErrorsTranslations)
66 for i := 0; i < len(ve); i++ {
67 fe = ve[i].(*fieldError)
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)
76 trans[fe.ns] = fe.Translate(ut)
82 // FieldError contains all functions to get error details
83 type FieldError interface {
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.
89 // eg. alias "iscolor": "hexcolor|rgb|rgba|hsl|hsla"
90 // will return "iscolor"
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.
97 // eg. alias "iscolor": "hexcolor|rgb|rgba|hsl|hsla"
98 // will return "hexcolor|rgb|rgba|hsl|hsla"
101 // returns the namespace for the field error, with the tag
102 // name taking precedence over the fields actual name.
104 // eg. JSON name "User.fname"
106 // See StructNamespace() for a version that returns actual names.
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
112 // returns the namespace for the field error, with the fields
115 // eq. "User.FirstName" see Namespace for comparison
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
121 // returns the fields name with the tag name taking precedence over the
122 // fields actual name.
124 // eq. JSON name "fname"
125 // see ActualField for comparison
128 // returns the fields actual name from the struct, when able to determine.
131 // see Field for comparison
134 // returns the actual fields value in case needed for creating the error
138 // returns the param value, in string form for comparison; this will also
139 // help with generating an error message
142 // Kind returns the Field's reflect Kind
144 // eg. time.Time's kind is a struct
147 // Type returns the Field's reflect Type
149 // // eg. time.Time's type is time.Time
152 // returns the FieldError's translated error
153 // from the provided 'ut.Translator' and registered 'TranslationFunc'
155 // NOTE: is not registered translation can be found it returns the same
156 // as calling fe.Error()
157 Translate(ut ut.Translator) string
160 // compile time interface checks
161 var _ FieldError = new(fieldError)
162 var _ error = new(fieldError)
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 {
181 // Tag returns the validation tag that failed.
182 func (fe *fieldError) Tag() string {
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 {
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 {
198 // StructNamespace returns the namespace for the field error, with the fields
200 func (fe *fieldError) StructNamespace() string {
204 // Field returns the fields name with the tag name taking precedence over the
205 // fields actual name.
206 func (fe *fieldError) Field() string {
208 return fe.ns[len(fe.ns)-int(fe.fieldLen):]
209 // // return fe.field
210 // fld := fe.ns[len(fe.ns)-int(fe.fieldLen):]
212 // log.Println("FLD:", fld)
214 // if len(fld) > 0 && fld[:1] == "." {
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):]
227 // Value returns the actual fields value in case needed for creating the error
229 func (fe *fieldError) Value() interface{} {
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 {
239 // Kind returns the Field's reflect Kind
240 func (fe *fieldError) Kind() reflect.Kind {
244 // Type returns the Field's reflect Type
245 func (fe *fieldError) Type() reflect.Type {
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)
254 // Translate returns the FieldError's translated error
255 // from the provided 'ut.Translator' and registered 'TranslationFunc'
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 {
261 m, ok := fe.v.transTagFunc[ut]