83 lines
2.0 KiB
Go
83 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"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
|
|
}
|
|
|
|
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.Field(), fe.Param(), fe.Value()}
|
|
},
|
|
},
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
errorList := make([]error, 0)
|
|
for _, e := range errs {
|
|
errorList = append(errorList, fmt.Errorf("%s", e.Translate(v.trans)))
|
|
}
|
|
return errors.Join(errorList...)
|
|
}
|