github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/system/validation/validation.go (about) 1 // This file is part of the Smart Home 2 // Program complex distribution https://github.com/e154/smart-home 3 // Copyright (C) 2016-2023, Filippov Alex 4 // 5 // This library is free software: you can redistribute it and/or 6 // modify it under the terms of the GNU Lesser General Public 7 // License as published by the Free Software Foundation; either 8 // version 3 of the License, or (at your option) any later version. 9 // 10 // This library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 // Library General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public 16 // License along with this library. If not, see 17 // <https://www.gnu.org/licenses/>. 18 19 package validation 20 21 import ( 22 "context" 23 "reflect" 24 "strings" 25 26 "github.com/go-playground/locales/en" 27 "github.com/go-playground/locales/ru" 28 ut "github.com/go-playground/universal-translator" 29 "github.com/go-playground/validator/v10" 30 en_translations "github.com/go-playground/validator/v10/translations/en" 31 "go.uber.org/fx" 32 33 "github.com/e154/smart-home/common/logger" 34 m "github.com/e154/smart-home/models" 35 ) 36 37 var ( 38 log = logger.MustGetLogger("validation") 39 ) 40 41 // Validate ... 42 type Validate struct { 43 validate *validator.Validate 44 trans ut.Translator 45 config *m.AppConfig 46 lang string 47 } 48 49 // NewValidate ... 50 func NewValidate(lc fx.Lifecycle, 51 config *m.AppConfig) (v *Validate) { 52 v = &Validate{ 53 lang: config.Lang, 54 } 55 56 lc.Append(fx.Hook{ 57 OnStart: func(ctx context.Context) error { 58 return v.Start(ctx) 59 }, 60 }) 61 62 return 63 } 64 65 // Start ... 66 func (v *Validate) Start(_ context.Context) (err error) { 67 68 log.Info("start ...") 69 70 _en := en.New() 71 uni := ut.New(_en, _en, ru.New()) 72 73 var ok bool 74 if v.trans, ok = uni.GetTranslator(v.lang); !ok { 75 v.trans, _ = uni.GetTranslator("en") 76 } 77 78 v.validate = validator.New() 79 v.validate.RegisterTagNameFunc(func(fld reflect.StructField) string { 80 tag := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] 81 if tag == "-" { 82 return "" 83 } 84 return tag 85 }) 86 87 err = en_translations.RegisterDefaultTranslations(v.validate, v.trans) 88 89 return 90 } 91 92 // ValidVar ... 93 func (v *Validate) ValidVar(s interface{}, key, tag string) (ok bool, errs validator.ValidationErrorsTranslations) { 94 err := v.validate.Var(s, tag) 95 if ok = err == nil; !ok { 96 if validationErrors, valid := err.(validator.ValidationErrors); valid { 97 errs = validationErrors.Translate(v.trans) 98 errs[key] = errs[""] 99 delete(errs, "") 100 } 101 } 102 return 103 } 104 105 // Valid ... 106 func (v *Validate) Valid(s interface{}) (ok bool, errs validator.ValidationErrorsTranslations) { 107 err := v.validate.Struct(s) 108 if ok = err == nil; !ok { 109 if validationErrors, valid := err.(validator.ValidationErrors); valid { 110 errs = validationErrors.Translate(v.trans) 111 } 112 return 113 } 114 return 115 }