mirror of
https://github.com/spf13/viper
synced 2024-12-22 19:47:01 +00:00
parent
ed0a9674c6
commit
e26d6aedc1
2 changed files with 19 additions and 11 deletions
20
viper.go
20
viper.go
|
@ -624,7 +624,7 @@ func (v *Viper) UnmarshalKey(key string, rawVal interface{}) error {
|
||||||
// on the fields of the structure are properly set.
|
// on the fields of the structure are properly set.
|
||||||
func Unmarshal(rawVal interface{}) error { return v.Unmarshal(rawVal) }
|
func Unmarshal(rawVal interface{}) error { return v.Unmarshal(rawVal) }
|
||||||
func (v *Viper) Unmarshal(rawVal interface{}) error {
|
func (v *Viper) Unmarshal(rawVal interface{}) error {
|
||||||
err := mapstructure.WeakDecode(v.AllSettings(), rawVal)
|
err := decode(v.AllSettings(), defaultDecoderConfig(rawVal))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -635,16 +635,19 @@ func (v *Viper) Unmarshal(rawVal interface{}) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// A wrapper around mapstructure.Decode that mimics the WeakDecode functionality
|
// defaultDecoderConfig returns default mapsstructure.DecoderConfig with suppot
|
||||||
// while erroring on non existing vals in the destination struct.
|
// of time.Duration values
|
||||||
func weakDecodeExact(input, output interface{}) error {
|
func defaultDecoderConfig(output interface{}) *mapstructure.DecoderConfig {
|
||||||
config := &mapstructure.DecoderConfig{
|
return &mapstructure.DecoderConfig{
|
||||||
ErrorUnused: true,
|
|
||||||
Metadata: nil,
|
Metadata: nil,
|
||||||
Result: output,
|
Result: output,
|
||||||
WeaklyTypedInput: true,
|
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)
|
decoder, err := mapstructure.NewDecoder(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -655,7 +658,10 @@ func weakDecodeExact(input, output interface{}) error {
|
||||||
// UnmarshalExact unmarshals the config into a Struct, erroring if a field is nonexistent
|
// UnmarshalExact unmarshals the config into a Struct, erroring if a field is nonexistent
|
||||||
// in the destination struct.
|
// in the destination struct.
|
||||||
func (v *Viper) UnmarshalExact(rawVal interface{}) error {
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -453,10 +453,12 @@ func TestRecursiveAliases(t *testing.T) {
|
||||||
func TestUnmarshal(t *testing.T) {
|
func TestUnmarshal(t *testing.T) {
|
||||||
SetDefault("port", 1313)
|
SetDefault("port", 1313)
|
||||||
Set("name", "Steve")
|
Set("name", "Steve")
|
||||||
|
Set("duration", "1s1ms")
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
Port int
|
Port int
|
||||||
Name string
|
Name string
|
||||||
|
Duration time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
var C config
|
var C config
|
||||||
|
@ -466,14 +468,14 @@ func TestUnmarshal(t *testing.T) {
|
||||||
t.Fatalf("unable to decode into struct, %v", err)
|
t.Fatalf("unable to decode into struct, %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, &C, &config{Name: "Steve", Port: 1313})
|
assert.Equal(t, &C, &config{Name: "Steve", Port: 1313, Duration: time.Second + time.Millisecond})
|
||||||
|
|
||||||
Set("port", 1234)
|
Set("port", 1234)
|
||||||
err = Unmarshal(&C)
|
err = Unmarshal(&C)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to decode into struct, %v", err)
|
t.Fatalf("unable to decode into struct, %v", err)
|
||||||
}
|
}
|
||||||
assert.Equal(t, &C, &config{Name: "Steve", Port: 1234})
|
assert.Equal(t, &C, &config{Name: "Steve", Port: 1234, Duration: time.Second + time.Millisecond})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBindPFlags(t *testing.T) {
|
func TestBindPFlags(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue