Support translating field errors when field is of kind reflect.Ptr

Previously, if fields were of kind `reflect.Ptr`, the translation of
validation errors used the default string, resulting in unexpected
output.

Now the default translations use the field's `Elem()` kind (for example
for `*string` the `Elem()` is `string`), resulting in much more natural
output.
pull/340/head
Geoff Baskwill 7 years ago
parent 48a433ba4b
commit 866bd2a946
  1. 56
      translations/en/en.go
  2. 39
      translations/en/en_test.go

@ -69,6 +69,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var t string var t string
var digits uint64 var digits uint64
var kind reflect.Kind
if idx := strings.Index(fe.Param(), "."); idx != -1 { if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:])) digits = uint64(len(fe.Param()[idx+1:]))
@ -79,7 +80,12 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
goto END goto END
} }
switch fe.Kind() { kind = fe.Kind()
if kind == reflect.Ptr {
kind = fe.Type().Elem().Kind()
}
switch kind {
case reflect.String: case reflect.String:
var c string var c string
@ -154,6 +160,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var t string var t string
var digits uint64 var digits uint64
var kind reflect.Kind
if idx := strings.Index(fe.Param(), "."); idx != -1 { if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:])) digits = uint64(len(fe.Param()[idx+1:]))
@ -164,7 +171,12 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
goto END goto END
} }
switch fe.Kind() { kind = fe.Kind()
if kind == reflect.Ptr {
kind = fe.Type().Elem().Kind()
}
switch kind {
case reflect.String: case reflect.String:
var c string var c string
@ -239,6 +251,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var t string var t string
var digits uint64 var digits uint64
var kind reflect.Kind
if idx := strings.Index(fe.Param(), "."); idx != -1 { if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:])) digits = uint64(len(fe.Param()[idx+1:]))
@ -249,7 +262,12 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
goto END goto END
} }
switch fe.Kind() { kind = fe.Kind()
if kind == reflect.Ptr {
kind = fe.Type().Elem().Kind()
}
switch kind {
case reflect.String: case reflect.String:
var c string var c string
@ -359,6 +377,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var t string var t string
var f64 float64 var f64 float64
var digits uint64 var digits uint64
var kind reflect.Kind
fn := func() (err error) { fn := func() (err error) {
@ -371,7 +390,12 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
switch fe.Kind() { kind = fe.Kind()
if kind == reflect.Ptr {
kind = fe.Type().Elem().Kind()
}
switch kind {
case reflect.String: case reflect.String:
var c string var c string
@ -472,6 +496,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var t string var t string
var f64 float64 var f64 float64
var digits uint64 var digits uint64
var kind reflect.Kind
fn := func() (err error) { fn := func() (err error) {
@ -484,7 +509,12 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
switch fe.Kind() { kind = fe.Kind()
if kind == reflect.Ptr {
kind = fe.Type().Elem().Kind()
}
switch kind {
case reflect.String: case reflect.String:
var c string var c string
@ -585,6 +615,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var t string var t string
var f64 float64 var f64 float64
var digits uint64 var digits uint64
var kind reflect.Kind
fn := func() (err error) { fn := func() (err error) {
@ -597,7 +628,12 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
switch fe.Kind() { kind = fe.Kind()
if kind == reflect.Ptr {
kind = fe.Type().Elem().Kind()
}
switch kind {
case reflect.String: case reflect.String:
var c string var c string
@ -698,6 +734,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var t string var t string
var f64 float64 var f64 float64
var digits uint64 var digits uint64
var kind reflect.Kind
fn := func() (err error) { fn := func() (err error) {
@ -710,7 +747,12 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
switch fe.Kind() { kind = fe.Kind()
if kind == reflect.Ptr {
kind = fe.Type().Elem().Kind()
}
switch kind {
case reflect.String: case reflect.String:
var c string var c string

@ -129,6 +129,13 @@ func TestTranslations(t *testing.T) {
UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future
MAC string `validate:"mac"` MAC string `validate:"mac"`
IsColor string `validate:"iscolor"` IsColor string `validate:"iscolor"`
StrPtrMinLen *string `validate:"min=10"`
StrPtrMaxLen *string `validate:"max=1"`
StrPtrLen *string `validate:"len=2"`
StrPtrLt *string `validate:"lt=1"`
StrPtrLte *string `validate:"lte=1"`
StrPtrGt *string `validate:"gt=10"`
StrPtrGte *string `validate:"gte=10"`
} }
var test Test var test Test
@ -171,6 +178,10 @@ func TestTranslations(t *testing.T) {
test.MultiByte = "1234feerf" test.MultiByte = "1234feerf"
s := "toolong"
test.StrPtrMaxLen = &s
test.StrPtrLen = &s
err = validate.Struct(test) err = validate.Struct(test)
NotEqual(t, err, nil) NotEqual(t, err, nil)
@ -565,6 +576,34 @@ func TestTranslations(t *testing.T) {
ns: "Test.RequiredMultiple", ns: "Test.RequiredMultiple",
expected: "RequiredMultiple is a required field", expected: "RequiredMultiple is a required field",
}, },
{
ns: "Test.StrPtrMinLen",
expected: "StrPtrMinLen must be at least 10 characters in length",
},
{
ns: "Test.StrPtrMaxLen",
expected: "StrPtrMaxLen must be a maximum of 1 character in length",
},
{
ns: "Test.StrPtrLen",
expected: "StrPtrLen must be 2 characters in length",
},
{
ns: "Test.StrPtrLt",
expected: "StrPtrLt must be less than 1 character in length",
},
{
ns: "Test.StrPtrLte",
expected: "StrPtrLte must be at maximum 1 character in length",
},
{
ns: "Test.StrPtrGt",
expected: "StrPtrGt must be greater than 10 characters in length",
},
{
ns: "Test.StrPtrGte",
expected: "StrPtrGte must be at least 10 characters in length",
},
} }
for _, tt := range tests { for _, tt := range tests {

Loading…
Cancel
Save