fix: conf anonymous overlay problem (#2847)

master
Kevin Wan 2 years ago committed by GitHub
parent aed312f3c0
commit a019a1f59f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -107,6 +107,20 @@ func MustLoad(path string, v any, opts ...Option) {
} }
} }
func addOrMergeFields(info map[string]fieldInfo, key, name string, fields map[string]fieldInfo) {
if prev, ok := info[key]; ok {
// merge fields
for k, v := range fields {
prev.children[k] = v
}
} else {
info[key] = fieldInfo{
name: name,
children: fields,
}
}
}
func buildFieldsInfo(tp reflect.Type) map[string]fieldInfo { func buildFieldsInfo(tp reflect.Type) map[string]fieldInfo {
tp = mapping.Deref(tp) tp = mapping.Deref(tp)
@ -134,11 +148,12 @@ func buildStructFieldsInfo(tp reflect.Type) map[string]fieldInfo {
if ft.Kind() == reflect.Struct { if ft.Kind() == reflect.Struct {
fields := buildFieldsInfo(ft) fields := buildFieldsInfo(ft)
for k, v := range fields { for k, v := range fields {
info[k] = v addOrMergeFields(info, k, v.name, v.children)
} }
} else { } else {
info[lowerCaseName] = fieldInfo{ info[lowerCaseName] = fieldInfo{
name: name, name: name,
children: make(map[string]fieldInfo),
} }
} }
continue continue
@ -154,17 +169,7 @@ func buildStructFieldsInfo(tp reflect.Type) map[string]fieldInfo {
fields = buildFieldsInfo(ft.Elem()) fields = buildFieldsInfo(ft.Elem())
} }
if prev, ok := info[lowerCaseName]; ok { addOrMergeFields(info, lowerCaseName, name, fields)
// merge fields
for k, v := range fields {
prev.children[k] = v
}
} else {
info[lowerCaseName] = fieldInfo{
name: name,
children: fields,
}
}
} }
return info return info

@ -420,6 +420,42 @@ func TestLoadFromYamlItemOverlay(t *testing.T) {
} }
} }
func TestLoadFromYamlItemOverlayReverse(t *testing.T) {
type (
Redis struct {
Host string
Port int
}
RedisKey struct {
Redis
Key string
}
Server struct {
Redis Redis
}
TestConfig struct {
Redis RedisKey
Server
}
)
input := []byte(`Redis:
Host: localhost
Port: 6379
Key: test
`)
var c TestConfig
if assert.NoError(t, LoadFromYamlBytes(input, &c)) {
assert.Equal(t, "localhost", c.Redis.Host)
assert.Equal(t, 6379, c.Redis.Port)
assert.Equal(t, "test", c.Redis.Key)
}
}
func TestLoadFromYamlItemOverlayWithMap(t *testing.T) { func TestLoadFromYamlItemOverlayWithMap(t *testing.T) {
type ( type (
Redis struct { Redis struct {

@ -12,7 +12,6 @@ import (
// PropertyError represents a configuration error message. // PropertyError represents a configuration error message.
type PropertyError struct { type PropertyError struct {
error
message string message string
} }

@ -108,7 +108,7 @@ func TestNopWriter(t *testing.T) {
w.Stack("foo") w.Stack("foo")
w.Stat("foo") w.Stat("foo")
w.Slow("foo") w.Slow("foo")
w.Close() _ = w.Close()
}) })
} }

Loading…
Cancel
Save