mirror of
https://github.com/gohugoio/hugo.git
synced 2024-12-26 12:13:43 +00:00
tpl/collections: Some more params merge adjustments
* If the end result is maps.Params, we need to lower the keys * Also make sure to handle nested maps of different type Update #6633
This commit is contained in:
parent
a67d95fe1a
commit
ccb1bf1abb
2 changed files with 25 additions and 3 deletions
|
@ -17,6 +17,8 @@ import (
|
|||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/gohugoio/hugo/common/maps"
|
||||
|
||||
"github.com/gohugoio/hugo/common/hreflect"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
@ -68,6 +70,9 @@ func mergeMap(dst, src reflect.Value) reflect.Value {
|
|||
|
||||
out := reflect.MakeMap(dst.Type())
|
||||
|
||||
// If the destination is Params, we must lower case all keys.
|
||||
_, lowerCase := dst.Interface().(maps.Params)
|
||||
|
||||
// Copy the destination map.
|
||||
for _, key := range dst.MapKeys() {
|
||||
v := dst.MapIndex(key)
|
||||
|
@ -81,15 +86,18 @@ func mergeMap(dst, src reflect.Value) reflect.Value {
|
|||
dv, found := caseInsensitiveLookup(dst, key)
|
||||
|
||||
if found {
|
||||
// If both are the same map type, merge.
|
||||
// If both are the same map key type, merge.
|
||||
dve := dv.Elem()
|
||||
if dve.Kind() == reflect.Map {
|
||||
sve := sv.Elem()
|
||||
if dve.Type() == sve.Type() {
|
||||
if dve.Type().Key() == sve.Type().Key() {
|
||||
out.SetMapIndex(key, mergeMap(dve, sve))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if lowerCase && key.Kind() == reflect.String {
|
||||
key = reflect.ValueOf(strings.ToLower(key.String()))
|
||||
}
|
||||
out.SetMapIndex(key, sv)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,11 +66,25 @@ func TestMerge(t *testing.T) {
|
|||
map[string]interface{}{"a": 42, "c": 3},
|
||||
maps.Params{"a": int(1), "b": int(2), "c": int(3)}, false},
|
||||
{
|
||||
// https://github.com/gohugoio/hugo/issues/6633
|
||||
"params dst, upper case src",
|
||||
maps.Params{"a": 1, "b": 2},
|
||||
map[string]interface{}{"a": 42, "C": 3},
|
||||
maps.Params{"a": int(1), "b": int(2), "c": int(3)}, false},
|
||||
{
|
||||
"params src",
|
||||
map[string]interface{}{"a": 1, "c": 2},
|
||||
maps.Params{"a": 42, "c": 3},
|
||||
map[string]interface{}{"a": int(1), "c": int(2)}, false},
|
||||
{
|
||||
"params src, upper case dst",
|
||||
map[string]interface{}{"a": 1, "C": 2},
|
||||
maps.Params{"a": 42, "c": 3},
|
||||
map[string]interface{}{"a": int(1), "C": int(2)}, false},
|
||||
{
|
||||
"nested, params dst",
|
||||
maps.Params{"a": 1, "b": maps.Params{"d": 1, "e": 2}},
|
||||
map[string]interface{}{"a": 42, "c": 3, "b": map[string]interface{}{"d": 55, "e": 66, "f": 3}},
|
||||
maps.Params{"a": 1, "b": maps.Params{"d": 1, "e": 2, "f": 3}, "c": 3}, false},
|
||||
{"src nil", simpleMap, nil, simpleMap, false},
|
||||
// Error cases.
|
||||
{"dst not a map", "not a map", nil, nil, true},
|
||||
|
|
Loading…
Reference in a new issue