diff --git a/go.mod b/go.mod index 76be69509..428accc65 100644 --- a/go.mod +++ b/go.mod @@ -32,6 +32,7 @@ require ( github.com/fatih/structs v1.1.0 github.com/glebarez/sqlite v1.8.0 github.com/go-http-utils/etag v0.0.0-20161124023236-513ea8f21eb1 + github.com/go-playground/validator/v10 v10.14.1 github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 github.com/godbus/dbus/v5 v5.1.0 github.com/gokrazy/updater v0.0.0-20230215172637-813ccc7f21e2 @@ -132,7 +133,6 @@ require ( github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.14.1 // indirect github.com/gobwas/httphead v0.1.0 // indirect github.com/gobwas/pool v0.2.1 // indirect github.com/gobwas/ws v1.2.1 // indirect diff --git a/util/decoder.go b/util/decoder.go index 068fb2c22..19cba3e43 100644 --- a/util/decoder.go +++ b/util/decoder.go @@ -1,9 +1,14 @@ package util import ( + "reflect" + + "github.com/go-playground/validator/v10" "github.com/mitchellh/mapstructure" ) +var validate = validator.New() + // DecodeOther uses mapstructure to decode into target structure. Unused keys cause errors. func DecodeOther(other, cc interface{}) error { decoderConfig := &mapstructure.DecoderConfig{ @@ -17,15 +22,20 @@ func DecodeOther(other, cc interface{}) error { } decoder, err := mapstructure.NewDecoder(decoderConfig) - if err == nil { - err = decoder.Decode(other) - } - if err != nil { - err = &ConfigError{err} + return err } - return err + if err := decoder.Decode(other); err != nil { + return &ConfigError{err} + } + + // validate structs + if rv := reflect.ValueOf(cc); rv.Kind() == reflect.Struct || rv.Kind() == reflect.Pointer && rv.Elem().Kind() == reflect.Struct { + return validate.Struct(cc) + } + + return nil } // ConfigError wraps yaml configuration errors from mapstructure