fix: problem on name overlaping in config (#2820)

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

@ -22,7 +22,6 @@ var loaders = map[string]func([]byte, any) error{
type fieldInfo struct { type fieldInfo struct {
name string name string
kind reflect.Kind
children map[string]fieldInfo children map[string]fieldInfo
} }
@ -140,7 +139,6 @@ func buildStructFieldsInfo(tp reflect.Type) map[string]fieldInfo {
} else { } else {
info[lowerCaseName] = fieldInfo{ info[lowerCaseName] = fieldInfo{
name: name, name: name,
kind: ft.Kind(),
} }
} }
continue continue
@ -156,12 +154,18 @@ func buildStructFieldsInfo(tp reflect.Type) map[string]fieldInfo {
fields = buildFieldsInfo(ft.Elem()) fields = buildFieldsInfo(ft.Elem())
} }
if prev, ok := info[lowerCaseName]; ok {
// merge fields
for k, v := range fields {
prev.children[k] = v
}
} else {
info[lowerCaseName] = fieldInfo{ info[lowerCaseName] = fieldInfo{
name: name, name: name,
kind: ft.Kind(),
children: fields, children: fields,
} }
} }
}
return info return info
} }

@ -384,6 +384,78 @@ func TestLoadFromYamlBytesLayers(t *testing.T) {
assert.Equal(t, "foo", val.Value) assert.Equal(t, "foo", val.Value)
} }
func TestLoadFromYamlItemOverlay(t *testing.T) {
type (
Redis struct {
Host string
Port int
}
RedisKey struct {
Redis
Key string
}
Server struct {
Redis RedisKey
}
TestConfig struct {
Server
Redis Redis
}
)
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.Server.Redis.Key)
}
}
func TestLoadFromYamlItemOverlayWithMap(t *testing.T) {
type (
Redis struct {
Host string
Port int
}
RedisKey struct {
Redis
Key string
}
Server struct {
Redis RedisKey
}
TestConfig struct {
Server
Redis map[string]interface{}
}
)
input := []byte(`Redis:
Host: localhost
Port: 6379
Key: test
`)
var c TestConfig
if assert.NoError(t, LoadFromYamlBytes(input, &c)) {
assert.Equal(t, "localhost", c.Server.Redis.Host)
assert.Equal(t, 6379, c.Server.Redis.Port)
assert.Equal(t, "test", c.Server.Redis.Key)
}
}
func TestUnmarshalJsonBytesMap(t *testing.T) { func TestUnmarshalJsonBytesMap(t *testing.T) {
input := []byte(`{"foo":{"/mtproto.RPCTos": "bff.bff","bar":"baz"}}`) input := []byte(`{"foo":{"/mtproto.RPCTos": "bff.bff","bar":"baz"}}`)

@ -4,6 +4,7 @@
```go ```go
type RestfulConf struct { type RestfulConf struct {
ServiceName string `json:",env=SERVICE_NAME"` // read from env automatically
Host string `json:",default=0.0.0.0"` Host string `json:",default=0.0.0.0"`
Port int Port int
LogMode string `json:",options=[file,console]"` LogMode string `json:",options=[file,console]"`
@ -21,20 +22,20 @@ type RestfulConf struct {
```yaml ```yaml
# most fields are optional or have default values # most fields are optional or have default values
Port: 8080 port: 8080
LogMode: console logMode: console
# you can use env settings # you can use env settings
MaxBytes: ${MAX_BYTES} maxBytes: ${MAX_BYTES}
``` ```
- toml example - toml example
```toml ```toml
# most fields are optional or have default values # most fields are optional or have default values
Port = 8_080 port = 8_080
LogMode = "console" logMode = "console"
# you can use env settings # you can use env settings
MaxBytes = "${MAX_BYTES}" maxBytes = "${MAX_BYTES}"
``` ```
3. Load the config from a file: 3. Load the config from a file:

Loading…
Cancel
Save