summaryrefslogtreecommitdiffstats
path: root/tpl/collections/reflect_helpers.go
diff options
context:
space:
mode:
Diffstat (limited to 'tpl/collections/reflect_helpers.go')
-rw-r--r--tpl/collections/reflect_helpers.go44
1 files changed, 43 insertions, 1 deletions
diff --git a/tpl/collections/reflect_helpers.go b/tpl/collections/reflect_helpers.go
index 074396479..85aa389ce 100644
--- a/tpl/collections/reflect_helpers.go
+++ b/tpl/collections/reflect_helpers.go
@@ -14,10 +14,11 @@
package collections
import (
- "errors"
"fmt"
"reflect"
"time"
+
+ "github.com/pkg/errors"
)
var (
@@ -59,6 +60,47 @@ func normalize(v reflect.Value) interface{} {
return v.Interface()
}
+// collects identities from the slices in seqs into a set. Numeric values are normalized,
+// pointers unwrapped.
+func collectIdentities(seqs ...interface{}) (map[interface{}]bool, error) {
+ seen := make(map[interface{}]bool)
+ for _, seq := range seqs {
+ v := reflect.ValueOf(seq)
+ switch v.Kind() {
+ case reflect.Array, reflect.Slice:
+ for i := 0; i < v.Len(); i++ {
+ ev, _ := indirectInterface(v.Index(i))
+ if !ev.Type().Comparable() {
+ return nil, errors.New("elements must be comparable")
+ }
+
+ seen[normalize(ev)] = true
+ }
+ default:
+ return nil, fmt.Errorf("arguments must be slices or arrays")
+ }
+ }
+
+ return seen, nil
+}
+
+// We have some different numeric and string types that we try to behave like
+// they were the same.
+func convertValue(v reflect.Value, to reflect.Type) (reflect.Value, error) {
+ if v.Type().AssignableTo(to) {
+ return v, nil
+ }
+ switch kind := to.Kind(); {
+ case kind == reflect.String:
+ s, err := toString(v)
+ return reflect.ValueOf(s), err
+ case isNumber(kind):
+ return convertNumber(v, kind)
+ default:
+ return reflect.Value{}, errors.Errorf("%s is not assignable to %s", v.Type(), to)
+ }
+}
+
// There are potential overflows in this function, but the downconversion of
// int64 etc. into int8 etc. is coming from the synthetic unit tests for Union etc.
// TODO(bep) We should consider normalizing the slices to int64 etc.