mirror of https://github.com/spf13/viper.git
handle int slice as well
This commit is contained in:
parent
aa2861e085
commit
7e17080926
45
viper.go
45
viper.go
|
@ -1149,19 +1149,11 @@ func unmarshalPostProcess(input any, opts ...DecoderConfigOption) error {
|
|||
return err
|
||||
}
|
||||
|
||||
v.postProcessingSliceFields(map[string]bool{}, structKeyMap, "")
|
||||
v.postProcessingSliceFields(structKeyMap, "")
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO remove shadow
|
||||
func (v *Viper) postProcessingSliceFields(shadow map[string]bool, m map[string]any, prefix string) map[string]bool {
|
||||
if shadow != nil && prefix != "" && shadow[prefix] {
|
||||
// prefix is shadowed => nothing more to flatten
|
||||
return shadow
|
||||
}
|
||||
if shadow == nil {
|
||||
shadow = make(map[string]bool)
|
||||
}
|
||||
func (v *Viper) postProcessingSliceFields(m map[string]any, prefix string) {
|
||||
|
||||
var m2 map[string]any
|
||||
if prefix != "" {
|
||||
|
@ -1173,21 +1165,29 @@ func (v *Viper) postProcessingSliceFields(shadow map[string]bool, m map[string]a
|
|||
if valValue.Kind() == reflect.Slice {
|
||||
for i := 0; i < valValue.Len(); i++ {
|
||||
item := valValue.Index(i)
|
||||
if item.Kind() != reflect.Struct || !item.CanSet() {
|
||||
iStr := strconv.FormatInt(int64(i), 10)
|
||||
|
||||
fmt.Printf("item %v\n", item)
|
||||
if !item.CanSet() {
|
||||
continue
|
||||
}
|
||||
itemType := item.Type()
|
||||
for j := 0; j < item.NumField(); j++ {
|
||||
field := itemType.Field(j)
|
||||
// fmt.Printf("Field %d: Name=%s, Type=%v, Value=%v\n", j, field.Name, field.Type, item.Field(j).Interface())
|
||||
|
||||
sliceKey := fmt.Sprintf("%s%s%s%d%s%s", prefix, k, v.keyDelim, i, v.keyDelim, field.Name)
|
||||
shadow[strings.ToLower(sliceKey)] = true
|
||||
// fmt.Printf("%s is slice\n", sliceKey)
|
||||
if item.Kind() == reflect.Struct {
|
||||
itemType := item.Type()
|
||||
for j := 0; j < item.NumField(); j++ {
|
||||
field := itemType.Field(j)
|
||||
sliceKey := prefix + k + v.keyDelim + iStr + v.keyDelim + field.Name
|
||||
// fmt.Printf("%s is slice\n", sliceKey)
|
||||
|
||||
if val, ok := v.getEnv(v.mergeWithEnvPrefix(sliceKey)); ok {
|
||||
// fmt.Printf("Val is %v\n", val)
|
||||
item.Field(j).SetString(val)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sliceKey := prefix + k + v.keyDelim + iStr
|
||||
if val, ok := v.getEnv(v.mergeWithEnvPrefix(sliceKey)); ok {
|
||||
// fmt.Printf("Val is %v\n", val)
|
||||
item.Field(j).SetString(val)
|
||||
intValue, _ := strconv.ParseInt(val, 10, 32)
|
||||
item.SetInt(intValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1202,9 +1202,8 @@ func (v *Viper) postProcessingSliceFields(shadow map[string]bool, m map[string]a
|
|||
continue
|
||||
}
|
||||
// recursively merge to shadow map
|
||||
shadow = v.postProcessingSliceFields(shadow, m2, fullKey)
|
||||
v.postProcessingSliceFields(m2, fullKey)
|
||||
}
|
||||
return shadow
|
||||
}
|
||||
|
||||
func (v *Viper) decodeStructKeys(input any, opts ...DecoderConfigOption) ([]string, error) {
|
||||
|
|
|
@ -2611,6 +2611,10 @@ name: Steve
|
|||
port: 8080
|
||||
auth:
|
||||
secret: 88888-88888
|
||||
modes:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
clients:
|
||||
- name: foo
|
||||
- name: bar
|
||||
|
@ -2641,6 +2645,7 @@ func TestSliceIndexAutomaticEnv(t *testing.T) {
|
|||
Port int
|
||||
Name string
|
||||
Auth AuthConfig
|
||||
Modes []int
|
||||
Clients []ClientConfig
|
||||
Proxy ProxyConfig
|
||||
}
|
||||
|
@ -2655,10 +2660,12 @@ func TestSliceIndexAutomaticEnv(t *testing.T) {
|
|||
assert.Equal(t, "foo", v.GetString("clients.0.name"))
|
||||
assert.Equal(t, "bar", v.GetString("clients.1.name"))
|
||||
assert.Equal(t, "proxy_foo", v.GetString("proxy.clients.0.name"))
|
||||
assert.Equal(t, []int{1, 2, 3}, v.GetIntSlice("modes"))
|
||||
|
||||
// Override with env variable
|
||||
t.Setenv("NAME", "Steven")
|
||||
t.Setenv("AUTH_SECRET", "99999-99999")
|
||||
t.Setenv("MODES_2", "300")
|
||||
t.Setenv("CLIENTS_1_NAME", "baz")
|
||||
t.Setenv("PROXY_CLIENTS_0_NAME", "ProxyFoo")
|
||||
|
||||
|
@ -2672,6 +2679,7 @@ func TestSliceIndexAutomaticEnv(t *testing.T) {
|
|||
assert.Equal(t, "Steven", config.Name)
|
||||
assert.Equal(t, 8080, config.Port)
|
||||
assert.Equal(t, "99999-99999", config.Auth.Secret)
|
||||
assert.Equal(t, []int{1, 2, 300}, config.Modes)
|
||||
assert.Equal(t, "foo", config.Clients[0].Name)
|
||||
assert.Equal(t, "baz", config.Clients[1].Name)
|
||||
assert.Equal(t, "ProxyFoo", config.Proxy.Clients[0].Name)
|
||||
|
|
Loading…
Reference in New Issue