From 8c1b96127969350e2a6acb8e677d3cca50de6e12 Mon Sep 17 00:00:00 2001 From: Yauhen Lazurkin Date: Fri, 23 Sep 2016 23:32:50 +0300 Subject: [PATCH] Issue-105 Add support of time.Duration in v.UnmarshalExact --- viper.go | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/viper.go b/viper.go index 1b381dd..4f15709 100644 --- a/viper.go +++ b/viper.go @@ -611,19 +611,7 @@ func (v *Viper) UnmarshalKey(key string, rawVal interface{}) error { // on the fields of the structure are properly set. func Unmarshal(rawVal interface{}) error { return v.Unmarshal(rawVal) } func (v *Viper) Unmarshal(rawVal interface{}) error { - config := &mapstructure.DecoderConfig{ - Metadata: nil, - Result: rawVal, - WeaklyTypedInput: true, - DecodeHook: mapstructure.StringToTimeDurationHookFunc(), - } - - decoder, err := mapstructure.NewDecoder(config) - if err != nil { - return err - } - - err = decoder.Decode(v.AllSettings()) + err := decode(v.AllSettings(), defaultDecoderConfig(rawVal)) if err != nil { return err @@ -634,16 +622,19 @@ func (v *Viper) Unmarshal(rawVal interface{}) error { return nil } -// A wrapper around mapstructure.Decode that mimics the WeakDecode functionality -// while erroring on non existing vals in the destination struct -func weakDecodeExact(input, output interface{}) error { - config := &mapstructure.DecoderConfig{ - ErrorUnused: true, +// defaultDecoderConfig returns default mapsstructure.DecoderConfig with suppot +// of time.Duration values +func defaultDecoderConfig(output interface{}) *mapstructure.DecoderConfig { + return &mapstructure.DecoderConfig{ Metadata: nil, Result: output, WeaklyTypedInput: true, + DecodeHook: mapstructure.StringToTimeDurationHookFunc(), } +} +// A wrapper around mapstructure.Decode that mimics the WeakDecode functionality +func decode(input interface{}, config *mapstructure.DecoderConfig) error { decoder, err := mapstructure.NewDecoder(config) if err != nil { return err @@ -654,7 +645,10 @@ func weakDecodeExact(input, output interface{}) error { // Unmarshals the config into a Struct, erroring if a field is non-existant // in the destination struct func (v *Viper) UnmarshalExact(rawVal interface{}) error { - err := weakDecodeExact(v.AllSettings(), rawVal) + config := defaultDecoderConfig(rawVal) + config.ErrorUnused = true + + err := decode(v.AllSettings(), config) if err != nil { return err