diff --git a/enviper.go b/enviper.go index edde5c5..cdab271 100644 --- a/enviper.go +++ b/enviper.go @@ -1,10 +1,11 @@ package enviper import ( - "github.com/mitchellh/mapstructure" "reflect" "strings" + "github.com/mitchellh/mapstructure" + "github.com/spf13/viper" ) @@ -73,53 +74,55 @@ func (e *Enviper) bindEnvs(in interface{}, prev ...string) { if ifv.Kind() == reflect.Ptr { ifv = ifv.Elem() } - for i := 0; i < ifv.NumField(); i++ { - fv := ifv.Field(i) - if fv.Kind() == reflect.Ptr { - if fv.IsZero() { - fv = reflect.New(fv.Type().Elem()).Elem() - } else { - fv = fv.Elem() - } - } - t := ifv.Type().Field(i) - tv, ok := t.Tag.Lookup(e.TagName()) - if ok { - if index := strings.Index(tv, ","); index != -1 { - if tv[:index] == "-" { - continue - } - // If "squash" is specified in the tag, we squash the field down. - if strings.Index(tv[index+1:], "squash") != -1 { - e.bindEnvs(fv.Interface(), prev...) - continue + switch ifv.Kind() { + case reflect.Struct: + for i := 0; i < ifv.NumField(); i++ { + fv := ifv.Field(i) + if fv.Kind() == reflect.Ptr { + if fv.IsZero() { + fv = reflect.New(fv.Type().Elem()).Elem() + } else { + fv = fv.Elem() } - - tv = tv[:index] } + t := ifv.Type().Field(i) + tv, ok := t.Tag.Lookup(e.TagName()) + if ok { + if index := strings.Index(tv, ","); index != -1 { + if tv[:index] == "-" { + continue + } + + // If "squash" is specified in the tag, we squash the field down. + if strings.Contains(tv[index+1:], "squash") { + e.bindEnvs(fv.Interface(), prev...) + continue + } - if tv == "" { + tv = tv[:index] + } + + if tv == "" { + tv = t.Name + } + } else { tv = t.Name } - } else { - tv = t.Name - } - switch fv.Kind() { - case reflect.Struct: + e.bindEnvs(fv.Interface(), append(prev, tv)...) - case reflect.Map: - iter := fv.MapRange() - for iter.Next() { - if key, ok := iter.Key().Interface().(string); ok { - e.bindEnvs(iter.Value().Interface(), append(prev, tv, key)...) - } + } + case reflect.Map: + iter := ifv.MapRange() + for iter.Next() { + if key, ok := iter.Key().Interface().(string); ok { + e.bindEnvs(iter.Value().Interface(), append(prev, key)...) } - default: - env := strings.Join(append(prev, tv), ".") - // Viper.BindEnv will never return error - // because env is always non empty string - _ = e.Viper.BindEnv(env) } + default: + env := strings.Join(prev, ".") + // Viper.BindEnv will never return error + // because env is always non empty string + _ = e.Viper.BindEnv(env) } } diff --git a/enviper_test.go b/enviper_test.go index 73bb1b6..f7f9e6c 100644 --- a/enviper_test.go +++ b/enviper_test.go @@ -91,6 +91,18 @@ func (s *UnmarshalSuite) TestOnlyEnvs() { //s.Equal(true, c.QuxMap["key1"].Quuux) } +func (s *UnmarshalSuite) TestPrimitiveMap() { + s.setupFileConfig() + + var c Config + e := enviper.New(s.v) + s.Nil(e.Unmarshal(&c)) + + s.Equal("val1", c.PrimitiveMap["key1"]) + s.Equal("val2", c.PrimitiveMap["key2"]) + s.Equal("", c.PrimitiveMap[""]) +} + func (s *UnmarshalSuite) TestOnlyConfig() { s.setupFileConfig() @@ -180,6 +192,8 @@ type Config struct { QuxMap map[string]struct { Quuux bool } + PrimitiveMap map[string]string + QUX `mapstructure:",squash"` TagTest string `custom_tag:"TAG_TEST"` TagValueWithOmitempty string `mapstructure:",omitempty"` diff --git a/fixture.yaml b/fixture.yaml index c9f33d0..88adae7 100644 --- a/fixture.yaml +++ b/fixture.yaml @@ -8,6 +8,9 @@ QuxMap: Quuux: false key2: Quuux: false +PrimitiveMap: + key1: val1 + key2: val2 Quuux: true quuux_ptr: Value: testptr2 \ No newline at end of file