tpl/collections: Make index work with slice as the last arg

Fixes #6496
This commit is contained in:
Bjørn Erik Pedersen 2019-11-11 13:54:57 +01:00
parent 79355043e8
commit 95ef93be66
No known key found for this signature in database
GPG key ID: 330E6E2BD4859D8F
2 changed files with 30 additions and 9 deletions

View file

@ -28,11 +28,27 @@ import (
// We deviate from the stdlib due to https://github.com/golang/go/issues/14751. // We deviate from the stdlib due to https://github.com/golang/go/issues/14751.
// //
// TODO(moorereason): merge upstream changes. // TODO(moorereason): merge upstream changes.
func (ns *Namespace) Index(item interface{}, indices ...interface{}) (interface{}, error) { func (ns *Namespace) Index(item interface{}, args ...interface{}) (interface{}, error) {
v := reflect.ValueOf(item) v := reflect.ValueOf(item)
if !v.IsValid() { if !v.IsValid() {
return nil, errors.New("index of untyped nil") return nil, errors.New("index of untyped nil")
} }
var indices []interface{}
if len(args) == 1 {
v := reflect.ValueOf(args[0])
if v.Kind() == reflect.Slice {
for i := 0; i < v.Len(); i++ {
indices = append(indices, v.Index(i).Interface())
}
}
}
if indices == nil {
indices = args
}
for _, i := range indices { for _, i := range indices {
index := reflect.ValueOf(i) index := reflect.ValueOf(i)
var isNil bool var isNil bool

View file

@ -14,6 +14,7 @@
package collections package collections
import ( import (
"fmt"
"testing" "testing"
qt "github.com/frankban/quicktest" qt "github.com/frankban/quicktest"
@ -40,22 +41,26 @@ func TestIndex(t *testing.T) {
{map[string]map[string]string{"a": {"b": "c"}}, []interface{}{"a", "b"}, "c", false}, {map[string]map[string]string{"a": {"b": "c"}}, []interface{}{"a", "b"}, "c", false},
{[]map[string]map[string]string{{"a": {"b": "c"}}}, []interface{}{0, "a", "b"}, "c", false}, {[]map[string]map[string]string{{"a": {"b": "c"}}}, []interface{}{0, "a", "b"}, "c", false},
{map[string]map[string]interface{}{"a": {"b": []string{"c", "d"}}}, []interface{}{"a", "b", 1}, "d", false}, {map[string]map[string]interface{}{"a": {"b": []string{"c", "d"}}}, []interface{}{"a", "b", 1}, "d", false},
{map[string]map[string]string{"a": {"b": "c"}}, []interface{}{[]string{"a", "b"}}, "c", false},
// errors // errors
{nil, nil, nil, true}, {nil, nil, nil, true},
{[]int{0, 1}, []interface{}{"1"}, nil, true}, {[]int{0, 1}, []interface{}{"1"}, nil, true},
{[]int{0, 1}, []interface{}{nil}, nil, true}, {[]int{0, 1}, []interface{}{nil}, nil, true},
{tstNoStringer{}, []interface{}{0}, nil, true}, {tstNoStringer{}, []interface{}{0}, nil, true},
} { } {
c.Run(fmt.Sprint(i), func(c *qt.C) {
errMsg := qt.Commentf("[%d] %v", i, test) errMsg := qt.Commentf("[%d] %v", i, test)
result, err := ns.Index(test.item, test.indices...) result, err := ns.Index(test.item, test.indices...)
if test.isErr { if test.isErr {
c.Assert(err, qt.Not(qt.IsNil), errMsg) c.Assert(err, qt.Not(qt.IsNil), errMsg)
continue return
} }
c.Assert(err, qt.IsNil, errMsg) c.Assert(err, qt.IsNil, errMsg)
c.Assert(result, qt.DeepEquals, test.expect, errMsg) c.Assert(result, qt.DeepEquals, test.expect, errMsg)
})
} }
} }