github.com/cs3org/reva/v2@v2.27.7/pkg/utils/cfg/cfg.go (about) 1 // Copyright 2018-2023 CERN 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // In applying this license, CERN does not waive the privileges and immunities 16 // granted to it by virtue of its status as an Intergovernmental Organization 17 // or submit itself to any jurisdiction. 18 19 package cfg 20 21 import ( 22 "errors" 23 "reflect" 24 25 "github.com/go-playground/locales/en" 26 ut "github.com/go-playground/universal-translator" 27 "github.com/go-playground/validator/v10" 28 en_translations "github.com/go-playground/validator/v10/translations/en" 29 "github.com/mitchellh/mapstructure" 30 ) 31 32 // Setter is the interface a configuration struct may implement 33 // to set the default options. 34 type Setter interface { 35 // ApplyDefaults applies the default options. 36 ApplyDefaults() 37 } 38 39 var validate = validator.New() 40 var english = en.New() 41 var uni = ut.New(english, english) 42 var trans, _ = uni.GetTranslator("en") 43 var _ = en_translations.RegisterDefaultTranslations(validate, trans) 44 45 func init() { 46 validate.RegisterTagNameFunc(func(field reflect.StructField) string { 47 if k := field.Tag.Get("mapstructure"); k != "" { 48 return k 49 } 50 // if not specified, fall back to field name 51 return field.Name 52 }) 53 } 54 55 // Decode decodes the given raw input interface to the target pointer c. 56 // It applies the default configuration if the target struct 57 // implements the Setter interface. 58 // It also perform a validation to all the fields of the configuration. 59 func Decode(input map[string]any, c any) error { 60 config := &mapstructure.DecoderConfig{ 61 Metadata: nil, 62 Result: c, 63 } 64 65 decoder, err := mapstructure.NewDecoder(config) 66 if err != nil { 67 return err 68 } 69 if err := decoder.Decode(input); err != nil { 70 return err 71 } 72 if s, ok := c.(Setter); ok { 73 s.ApplyDefaults() 74 } 75 76 return translateError(validate.Struct(c), trans) 77 } 78 79 func translateError(err error, trans ut.Translator) error { 80 if err == nil { 81 return nil 82 } 83 errs := err.(validator.ValidationErrors) 84 translated := make([]error, 0, len(errs)) 85 for _, err := range errs { 86 translated = append(translated, errors.New(err.Translate(trans))) 87 } 88 return errors.Join(translated...) 89 }