From 2db0a95f34fabcd697d31c93648d1798ecb3a071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Sun, 12 Jan 2025 21:12:48 +0200 Subject: [PATCH] tpl/collections: Use SetIterKey/SetIterValue for Where, Sort and Merge --- tpl/collections/merge.go | 18 +++++++++++++----- tpl/collections/sort.go | 7 +++++-- tpl/collections/where.go | 6 ++++-- tpl/internal/go_templates/fmtsort/sort.go | 6 +++++- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/tpl/collections/merge.go b/tpl/collections/merge.go index 36343117a30..6dbe98065a9 100644 --- a/tpl/collections/merge.go +++ b/tpl/collections/merge.go @@ -75,9 +75,11 @@ func caseInsensitiveLookup(m, k reflect.Value) (reflect.Value, bool) { return v, hreflect.IsTruthfulValue(v) } + k2 := reflect.New(m.Type().Key()).Elem() + iter := m.MapRange() for iter.Next() { - k2 := iter.Key() + k2.SetIterKey(iter) if strings.EqualFold(k.String(), k2.String()) { return iter.Value(), true } @@ -92,20 +94,26 @@ func mergeMap(dst, src reflect.Value) reflect.Value { // If the destination is Params, we must lower case all keys. _, lowerCase := dst.Interface().(maps.Params) + k := reflect.New(dst.Type().Key()).Elem() + v := reflect.New(dst.Type().Elem()).Elem() + // Copy the destination map. iter := dst.MapRange() for iter.Next() { - k := iter.Key() - v := iter.Value() + k.SetIterKey(iter) + v.SetIterValue(iter) out.SetMapIndex(k, v) } // Add all keys in src not already in destination. // Maps of the same type will be merged. + k = reflect.New(src.Type().Key()).Elem() + sv := reflect.New(src.Type().Elem()).Elem() + iter = src.MapRange() for iter.Next() { - k := iter.Key() - sv := iter.Value() + k.SetIterKey(iter) + sv.SetIterValue(iter) dv, found := caseInsensitiveLookup(dst, k) if found { diff --git a/tpl/collections/sort.go b/tpl/collections/sort.go index edd573d8deb..51ae0e7f1a9 100644 --- a/tpl/collections/sort.go +++ b/tpl/collections/sort.go @@ -99,11 +99,14 @@ func (ns *Namespace) Sort(ctx context.Context, l any, args ...any) (any, error) } case reflect.Map: + key := reflect.New(seqv.Type().Key()).Elem() + value := reflect.New(seqv.Type().Elem()).Elem() + iter := seqv.MapRange() i := 0 for iter.Next() { - key := iter.Key() - value := iter.Value() + key.SetIterKey(iter) + value.SetIterValue(iter) p.Pairs[i].Value = value if sortByField == "" { p.Pairs[i].Key = key diff --git a/tpl/collections/where.go b/tpl/collections/where.go index 04e6d4166f9..a14a4863d37 100644 --- a/tpl/collections/where.go +++ b/tpl/collections/where.go @@ -441,10 +441,12 @@ func (ns *Namespace) checkWhereArray(ctxv, seqv, kv, mv reflect.Value, path []st // checkWhereMap handles the where-matching logic when the seqv value is a Map. func (ns *Namespace) checkWhereMap(ctxv, seqv, kv, mv reflect.Value, path []string, op string) (any, error) { rv := reflect.MakeMap(seqv.Type()) + k := reflect.New(seqv.Type().Key()).Elem() + elemv := reflect.New(seqv.Type().Elem()).Elem() iter := seqv.MapRange() for iter.Next() { - k := iter.Key() - elemv := iter.Value() + k.SetIterKey(iter) + elemv.SetIterValue(iter) switch elemv.Kind() { case reflect.Array, reflect.Slice: r, err := ns.checkWhereArray(ctxv, elemv, kv, mv, path, op) diff --git a/tpl/internal/go_templates/fmtsort/sort.go b/tpl/internal/go_templates/fmtsort/sort.go index f51cdc7083a..443af02a7b2 100644 --- a/tpl/internal/go_templates/fmtsort/sort.go +++ b/tpl/internal/go_templates/fmtsort/sort.go @@ -55,9 +55,13 @@ func Sort(mapValue reflect.Value) SortedMap { // yelling loudly if that happens. See issue 33275. n := mapValue.Len() sorted := make(SortedMap, 0, n) + k := reflect.New(mapValue.Type().Key()).Elem() + v := reflect.New(mapValue.Type().Elem()).Elem() iter := mapValue.MapRange() for iter.Next() { - sorted = append(sorted, KeyValue{iter.Key(), iter.Value()}) + k.SetIterKey(iter) + v.SetIterValue(iter) + sorted = append(sorted, KeyValue{k, v}) } slices.SortStableFunc(sorted, func(a, b KeyValue) int { return compare(a.Key, b.Key)