fix: key like TLSConfig not working (#2730)
* fix: key like TLSConfig not working * fix: remove unnecessary code * chore: rename variable
This commit is contained in:
@@ -13,8 +13,6 @@ import (
|
|||||||
"github.com/zeromicro/go-zero/internal/encoding"
|
"github.com/zeromicro/go-zero/internal/encoding"
|
||||||
)
|
)
|
||||||
|
|
||||||
const distanceBetweenUpperAndLower = 32
|
|
||||||
|
|
||||||
var loaders = map[string]func([]byte, interface{}) error{
|
var loaders = map[string]func([]byte, interface{}) error{
|
||||||
".json": LoadFromJsonBytes,
|
".json": LoadFromJsonBytes,
|
||||||
".toml": LoadFromTomlBytes,
|
".toml": LoadFromTomlBytes,
|
||||||
@@ -66,9 +64,9 @@ func LoadFromJsonBytes(content []byte, v interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
finfo := buildFieldsInfo(reflect.TypeOf(v))
|
finfo := buildFieldsInfo(reflect.TypeOf(v))
|
||||||
camelCaseKeyMap := toCamelCaseKeyMap(m, finfo)
|
lowerCaseKeyMap := toLowerCaseKeyMap(m, finfo)
|
||||||
|
|
||||||
return mapping.UnmarshalJsonMap(camelCaseKeyMap, v, mapping.WithCanonicalKeyFunc(toCamelCase))
|
return mapping.UnmarshalJsonMap(lowerCaseKeyMap, v, mapping.WithCanonicalKeyFunc(toLowerCase))
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadConfigFromJsonBytes loads config into v from content json bytes.
|
// LoadConfigFromJsonBytes loads config into v from content json bytes.
|
||||||
@@ -129,7 +127,7 @@ func buildStructFieldsInfo(tp reflect.Type) map[string]fieldInfo {
|
|||||||
for i := 0; i < tp.NumField(); i++ {
|
for i := 0; i < tp.NumField(); i++ {
|
||||||
field := tp.Field(i)
|
field := tp.Field(i)
|
||||||
name := field.Name
|
name := field.Name
|
||||||
ccName := toCamelCase(name)
|
lowerCaseName := toLowerCase(name)
|
||||||
ft := mapping.Deref(field.Type)
|
ft := mapping.Deref(field.Type)
|
||||||
|
|
||||||
// flatten anonymous fields
|
// flatten anonymous fields
|
||||||
@@ -140,7 +138,7 @@ func buildStructFieldsInfo(tp reflect.Type) map[string]fieldInfo {
|
|||||||
info[k] = v
|
info[k] = v
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
info[ccName] = fieldInfo{
|
info[lowerCaseName] = fieldInfo{
|
||||||
name: name,
|
name: name,
|
||||||
kind: ft.Kind(),
|
kind: ft.Kind(),
|
||||||
}
|
}
|
||||||
@@ -158,7 +156,7 @@ func buildStructFieldsInfo(tp reflect.Type) map[string]fieldInfo {
|
|||||||
fields = buildFieldsInfo(ft.Elem())
|
fields = buildFieldsInfo(ft.Elem())
|
||||||
}
|
}
|
||||||
|
|
||||||
info[ccName] = fieldInfo{
|
info[lowerCaseName] = fieldInfo{
|
||||||
name: name,
|
name: name,
|
||||||
kind: ft.Kind(),
|
kind: ft.Kind(),
|
||||||
children: fields,
|
children: fields,
|
||||||
@@ -168,58 +166,18 @@ func buildStructFieldsInfo(tp reflect.Type) map[string]fieldInfo {
|
|||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
func toCamelCase(s string) string {
|
func toLowerCase(s string) string {
|
||||||
var buf strings.Builder
|
return strings.ToLower(s)
|
||||||
buf.Grow(len(s))
|
|
||||||
var capNext bool
|
|
||||||
boundary := true
|
|
||||||
for _, v := range s {
|
|
||||||
isCap := v >= 'A' && v <= 'Z'
|
|
||||||
isLow := v >= 'a' && v <= 'z'
|
|
||||||
if boundary && (isCap || isLow) {
|
|
||||||
if capNext {
|
|
||||||
if isLow {
|
|
||||||
v -= distanceBetweenUpperAndLower
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if isCap {
|
|
||||||
v += distanceBetweenUpperAndLower
|
|
||||||
}
|
|
||||||
}
|
|
||||||
boundary = false
|
|
||||||
}
|
|
||||||
if isCap || isLow {
|
|
||||||
buf.WriteRune(v)
|
|
||||||
capNext = false
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
switch v {
|
|
||||||
// '.' is used for chained keys, e.g. "grand.parent.child"
|
|
||||||
case ' ', '.', '\t':
|
|
||||||
buf.WriteRune(v)
|
|
||||||
capNext = false
|
|
||||||
boundary = true
|
|
||||||
case '_':
|
|
||||||
capNext = true
|
|
||||||
boundary = true
|
|
||||||
default:
|
|
||||||
buf.WriteRune(v)
|
|
||||||
capNext = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf.String()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func toCamelCaseInterface(v interface{}, info map[string]fieldInfo) interface{} {
|
func toLowerCaseInterface(v interface{}, info map[string]fieldInfo) interface{} {
|
||||||
switch vv := v.(type) {
|
switch vv := v.(type) {
|
||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
return toCamelCaseKeyMap(vv, info)
|
return toLowerCaseKeyMap(vv, info)
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
var arr []interface{}
|
var arr []interface{}
|
||||||
for _, vvv := range vv {
|
for _, vvv := range vv {
|
||||||
arr = append(arr, toCamelCaseInterface(vvv, info))
|
arr = append(arr, toLowerCaseInterface(vvv, info))
|
||||||
}
|
}
|
||||||
return arr
|
return arr
|
||||||
default:
|
default:
|
||||||
@@ -227,19 +185,19 @@ func toCamelCaseInterface(v interface{}, info map[string]fieldInfo) interface{}
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toCamelCaseKeyMap(m map[string]interface{}, info map[string]fieldInfo) map[string]interface{} {
|
func toLowerCaseKeyMap(m map[string]interface{}, info map[string]fieldInfo) map[string]interface{} {
|
||||||
res := make(map[string]interface{})
|
res := make(map[string]interface{})
|
||||||
|
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
ti, ok := info[k]
|
ti, ok := info[k]
|
||||||
if ok {
|
if ok {
|
||||||
res[k] = toCamelCaseInterface(v, ti.children)
|
res[k] = toLowerCaseInterface(v, ti.children)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
cck := toCamelCase(k)
|
lk := toLowerCase(k)
|
||||||
if ti, ok = info[cck]; ok {
|
if ti, ok = info[lk]; ok {
|
||||||
res[toCamelCase(k)] = toCamelCaseInterface(v, ti.children)
|
res[lk] = toLowerCaseInterface(v, ti.children)
|
||||||
} else {
|
} else {
|
||||||
res[k] = v
|
res[k] = v
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -237,23 +237,23 @@ func TestToCamelCase(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: "hello_world",
|
input: "hello_world",
|
||||||
expect: "helloWorld",
|
expect: "hello_world",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: "Hello_world",
|
input: "Hello_world",
|
||||||
expect: "helloWorld",
|
expect: "hello_world",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: "hello_World",
|
input: "hello_World",
|
||||||
expect: "helloWorld",
|
expect: "hello_world",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: "helloWorld",
|
input: "helloWorld",
|
||||||
expect: "helloWorld",
|
expect: "helloworld",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: "HelloWorld",
|
input: "HelloWorld",
|
||||||
expect: "helloWorld",
|
expect: "helloworld",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: "hello World",
|
input: "hello World",
|
||||||
@@ -269,34 +269,34 @@ func TestToCamelCase(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: "Hello World foo_bar",
|
input: "Hello World foo_bar",
|
||||||
expect: "hello world fooBar",
|
expect: "hello world foo_bar",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: "Hello World foo_Bar",
|
input: "Hello World foo_Bar",
|
||||||
expect: "hello world fooBar",
|
expect: "hello world foo_bar",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: "Hello World Foo_bar",
|
input: "Hello World Foo_bar",
|
||||||
expect: "hello world fooBar",
|
expect: "hello world foo_bar",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: "Hello World Foo_Bar",
|
input: "Hello World Foo_Bar",
|
||||||
expect: "hello world fooBar",
|
expect: "hello world foo_bar",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: "Hello.World Foo_Bar",
|
input: "Hello.World Foo_Bar",
|
||||||
expect: "hello.world fooBar",
|
expect: "hello.world foo_bar",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: "你好 World Foo_Bar",
|
input: "你好 World Foo_Bar",
|
||||||
expect: "你好 world fooBar",
|
expect: "你好 world foo_bar",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
test := test
|
test := test
|
||||||
t.Run(test.input, func(t *testing.T) {
|
t.Run(test.input, func(t *testing.T) {
|
||||||
assert.Equal(t, test.expect, toCamelCase(test.input))
|
assert.Equal(t, test.expect, toLowerCase(test.input))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -332,6 +332,22 @@ func TestLoadFromYamlBytes(t *testing.T) {
|
|||||||
assert.Equal(t, "foo", val.Layer1.Layer2.Layer3)
|
assert.Equal(t, "foo", val.Layer1.Layer2.Layer3)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLoadFromYamlBytesTerm(t *testing.T) {
|
||||||
|
input := []byte(`layer1:
|
||||||
|
layer2:
|
||||||
|
tls_conf: foo`)
|
||||||
|
var val struct {
|
||||||
|
Layer1 struct {
|
||||||
|
Layer2 struct {
|
||||||
|
Layer3 string `json:"tls_conf"`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NoError(t, LoadFromYamlBytes(input, &val))
|
||||||
|
assert.Equal(t, "foo", val.Layer1.Layer2.Layer3)
|
||||||
|
}
|
||||||
|
|
||||||
func TestLoadFromYamlBytesLayers(t *testing.T) {
|
func TestLoadFromYamlBytesLayers(t *testing.T) {
|
||||||
input := []byte(`layer1:
|
input := []byte(`layer1:
|
||||||
layer2:
|
layer2:
|
||||||
|
|||||||
Reference in New Issue
Block a user