From 8b0d4fa1e1f5c7ccb274615c486b3f8e61bb18f8 Mon Sep 17 00:00:00 2001 From: Rangel Reale Date: Fri, 3 Mar 2023 16:50:17 -0300 Subject: [PATCH] manual translator function registration --- translations/en/en.go | 32 ++++++++++++++++++++++++++------ validator_instance.go | 37 +++++++++++++++++++++++++++++-------- 2 files changed, 55 insertions(+), 14 deletions(-) diff --git a/translations/en/en.go b/translations/en/en.go index f007d34..19d23d1 100644 --- a/translations/en/en.go +++ b/translations/en/en.go @@ -16,6 +16,19 @@ import ( // RegisterDefaultTranslations registers a set of default translations // for all built in tag's in validator; you may add your own as desired. func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (err error) { + tf, err := RegisterDefaultTranslationsFunc(trans) + if err != nil { + return err + } + + return v.RegisterTranslationsFunc(trans, tf) +} + +// RegisterDefaultTranslationsFunc registers a set of default translations +// for all built in tag's in validator; you may add your own as desired. +// This version returns a map[tag]validator.TranslationFunc, which can be set on a validator using +// validator.Validate.RegisterTranslationsFunc. +func RegisterDefaultTranslationsFunc(trans ut.Translator) (map[string]validator.TranslationFunc, error) { translations := []struct { tag string translation string @@ -1363,24 +1376,31 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er }, } + var err error + ret := map[string]validator.TranslationFunc{} + for _, t := range translations { if t.customTransFunc != nil && t.customRegisFunc != nil { - err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, t.customTransFunc) + ret[t.tag] = t.customTransFunc + err = t.customRegisFunc(trans) } else if t.customTransFunc != nil && t.customRegisFunc == nil { - err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), t.customTransFunc) + ret[t.tag] = t.customTransFunc + err = registrationFunc(t.tag, t.translation, t.override)(trans) } else if t.customTransFunc == nil && t.customRegisFunc != nil { - err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, translateFunc) + ret[t.tag] = translateFunc + err = t.customRegisFunc(trans) } else { - err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), translateFunc) + ret[t.tag] = translateFunc + err = registrationFunc(t.tag, t.translation, t.override)(trans) } if err != nil { - return + return nil, err } } - return + return ret, nil } func registrationFunc(tag string, translation string, override bool) validator.RegisterTranslationsFunc { diff --git a/validator_instance.go b/validator_instance.go index 9493da4..3f67ec3 100644 --- a/validator_instance.go +++ b/validator_instance.go @@ -190,14 +190,14 @@ func (v *Validate) ValidateMap(data map[string]interface{}, rules map[string]int // // eg. to use the names which have been specified for JSON representations of structs, rather than normal Go field names: // -// validate.RegisterTagNameFunc(func(fld reflect.StructField) string { -// name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] -// // skip if tag key says it should be ignored -// if name == "-" { -// return "" -// } -// return name -// }) +// validate.RegisterTagNameFunc(func(fld reflect.StructField) string { +// name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] +// // skip if tag key says it should be ignored +// if name == "-" { +// return "" +// } +// return name +// }) func (v *Validate) RegisterTagNameFunc(fn TagNameFunc) { v.tagNameFunc = fn v.hasTagNameFunc = true @@ -350,6 +350,27 @@ func (v *Validate) RegisterTranslation(tag string, trans ut.Translator, register return } +// RegisterTranslationsFunc registers translations against the provided tag. +// This assumes that the tag translations have already been added to the Translator. +func (v *Validate) RegisterTranslationsFunc(trans ut.Translator, translationsFn map[string]TranslationFunc) (err error) { + + if v.transTagFunc == nil { + v.transTagFunc = make(map[ut.Translator]map[string]TranslationFunc) + } + + m, ok := v.transTagFunc[trans] + if !ok { + m = make(map[string]TranslationFunc) + v.transTagFunc[trans] = m + } + + for tag, fn := range translationsFn { + m[tag] = fn + } + + return +} + // Struct validates a structs exposed fields, and automatically validates nested structs, unless otherwise specified. // // It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.