Skip to content

Commit 7891132

Browse files
committed
fix(reflect): handle deep get of map with dot(s) in key name
1 parent 264523d commit 7891132

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

internal/template/reflect.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,24 @@ func deepGetImpl(v reflect.Value, path []string) interface{} {
4141
case reflect.Struct:
4242
return deepGetImpl(v.FieldByName(path[0]), path[1:])
4343
case reflect.Map:
44-
return deepGetImpl(v.MapIndex(reflect.ValueOf(path[0])), path[1:])
44+
// If the first part of the path is a key in the map, we use it directly
45+
if mapValue := v.MapIndex(reflect.ValueOf(path[0])); mapValue.IsValid() {
46+
return deepGetImpl(mapValue, path[1:])
47+
}
48+
49+
// If the first part of the path is not a key in the map, we try to find a valid key by joining the path parts
50+
for i := 2; i <= len(path); i++ {
51+
joinedPath := strings.Join(path[0:i], ".")
52+
if mapValue := v.MapIndex(reflect.ValueOf(joinedPath)); mapValue.IsValid() {
53+
if i == len(path) {
54+
return mapValue.Interface()
55+
}
56+
return deepGetImpl(mapValue, path[i:])
57+
}
58+
}
59+
60+
log.Printf("unable to find key from the path expression %s in map %v\n", strings.Join(path, "."), v)
61+
return nil
4562
case reflect.Slice, reflect.Array:
4663
i, err := parseAllocateInt(path[0])
4764
if err != nil {

internal/template/reflect_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,28 @@ func TestDeepGet(t *testing.T) {
7474
"...",
7575
"foo",
7676
},
77+
{
78+
"map with dot in key",
79+
map[string]map[string]string{
80+
"Foo": {
81+
"foo.bar.baz.qux": "quux",
82+
},
83+
},
84+
"Foo.foo.bar.baz.qux",
85+
"quux",
86+
},
87+
{
88+
"nested maps with dot in keys",
89+
map[string]map[string]map[string]string{
90+
"Foo": {
91+
"foo.bar": {
92+
"baz.qux": "quux",
93+
},
94+
},
95+
},
96+
"Foo.foo.bar.baz.qux",
97+
"quux",
98+
},
7799
{"struct", s, "X", "foo"},
78100
{"pointer to struct", sp, "X", "foo"},
79101
{"double pointer to struct", &sp, ".X", nil},

0 commit comments

Comments
 (0)