107 lines
2.4 KiB
Go
107 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/go-playground/locales/en"
|
|
ut "github.com/go-playground/universal-translator"
|
|
"github.com/go-playground/validator/v10"
|
|
en_translations "github.com/go-playground/validator/v10/translations/en"
|
|
)
|
|
|
|
type Validator struct {
|
|
validate *validator.Validate
|
|
trans ut.Translator
|
|
}
|
|
|
|
func (v Validator) Struct(i interface{}) error {
|
|
err := v.validate.Struct(i)
|
|
return v.Translate(err)
|
|
}
|
|
|
|
type Translation struct {
|
|
format string
|
|
params func(fe validator.FieldError) []any
|
|
}
|
|
|
|
var translations = map[string]Translation{
|
|
"oneof": {
|
|
"{0} must be one of [{1}], got '{2}'",
|
|
func(fe validator.FieldError) []any {
|
|
return []any{fe.Namespace(), fe.Param(), fe.Value()}
|
|
},
|
|
},
|
|
}
|
|
|
|
type TranslatedFieldError struct {
|
|
validator.FieldError
|
|
msg string
|
|
}
|
|
|
|
func NewTranslatedFieldError(msg string, e validator.FieldError) TranslatedFieldError {
|
|
return TranslatedFieldError{
|
|
FieldError: e,
|
|
msg: msg,
|
|
}
|
|
}
|
|
|
|
func (e TranslatedFieldError) Error() string {
|
|
return e.msg
|
|
}
|
|
|
|
func NewValidator() (*Validator, error) {
|
|
validate := validator.New(validator.WithRequiredStructEnabled())
|
|
language := en.New()
|
|
translator := ut.New(language, language)
|
|
trans, ok := translator.GetTranslator("en")
|
|
if !ok {
|
|
return nil, fmt.Errorf("Could not find translator to print error meesage")
|
|
}
|
|
en_translations.RegisterDefaultTranslations(validate, trans)
|
|
|
|
for validation, translation := range translations {
|
|
validate.RegisterTranslation(validation, trans,
|
|
func(ut ut.Translator) error {
|
|
return ut.Add(validation, translation.format, true)
|
|
},
|
|
func(ut ut.Translator, fe validator.FieldError) string {
|
|
params := translation.params(fe)
|
|
stringParams := make([]string, len(params))
|
|
for i, param := range params {
|
|
stringParams[i] = fmt.Sprintf("%s", param)
|
|
}
|
|
t, _ := ut.T(validation, stringParams...)
|
|
return t
|
|
})
|
|
}
|
|
|
|
return &Validator{
|
|
validate: validate,
|
|
trans: trans,
|
|
}, nil
|
|
}
|
|
|
|
func (v Validator) ValidateStruct(s interface{}) error {
|
|
err := v.validate.Struct(s)
|
|
return v.Translate(err)
|
|
}
|
|
|
|
func (v Validator) Translate(err error) error {
|
|
if err == nil {
|
|
return err
|
|
}
|
|
errs, ok := err.(validator.ValidationErrors)
|
|
if !ok {
|
|
return err
|
|
}
|
|
|
|
var errorList validator.ValidationErrors = nil
|
|
for _, e := range errs {
|
|
var translation validator.FieldError = TranslatedFieldError{
|
|
FieldError: e,
|
|
msg: e.Translate(v.trans),
|
|
}
|
|
errorList = append(errorList, translation)
|
|
}
|
|
return errorList
|
|
}
|