Skip to content

Commit ba97c37

Browse files
committed
feat: Support indexing slices and arrays in deepGet
1 parent 8648033 commit ba97c37

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

internal/template/reflect.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package template
22

33
import (
44
"log"
5+
"math"
56
"reflect"
7+
"strconv"
68
"strings"
79
)
810

@@ -26,6 +28,21 @@ func deepGetImpl(v reflect.Value, path []string) interface{} {
2628
return deepGetImpl(v.FieldByName(path[0]), path[1:])
2729
case reflect.Map:
2830
return deepGetImpl(v.MapIndex(reflect.ValueOf(path[0])), path[1:])
31+
case reflect.Slice, reflect.Array:
32+
iu64, err := strconv.ParseUint(path[0], 10, 64)
33+
if err != nil {
34+
log.Printf("non-negative decimal number required for array/slice index, got %#v\n", path[0])
35+
return nil
36+
}
37+
if iu64 > math.MaxInt {
38+
iu64 = math.MaxInt
39+
}
40+
i := int(iu64)
41+
if i >= v.Len() {
42+
log.Printf("index %v out of bounds", i)
43+
return nil
44+
}
45+
return deepGetImpl(v.Index(i), path[1:])
2946
default:
3047
log.Printf("unable to index by %s (value %v, kind %s)\n", path[0], v, v.Kind())
3148
return nil

internal/template/reflect_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@ func TestDeepGet(t *testing.T) {
7777
{"struct", s, "X", "foo"},
7878
{"pointer to struct", sp, "X", "foo"},
7979
{"double pointer to struct", &sp, ".X", nil},
80+
{"slice index", []string{"foo", "bar"}, "1", "bar"},
81+
{"slice index out of bounds", []string{}, "0", nil},
82+
{"slice index negative", []string{}, "-1", nil},
83+
{"slice index nonnumber", []string{}, "foo", nil},
84+
{"array index", [2]string{"foo", "bar"}, "1", "bar"},
85+
{"array index out of bounds", [1]string{"foo"}, "1", nil},
86+
{"array index negative", [1]string{"foo"}, "-1", nil},
87+
{"array index nonnumber", [1]string{"foo"}, "foo", nil},
8088
} {
8189
t.Run(tc.desc, func(t *testing.T) {
8290
got := deepGet(tc.item, tc.path)

0 commit comments

Comments
 (0)