summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Henderson <dhenderson@gmail.com>2017-11-02 22:13:15 -0400
committerDave Henderson <dhenderson@gmail.com>2017-11-02 22:13:15 -0400
commit22922aeb84e96fe387cec69c9d5aaef1492ff4d6 (patch)
tree84b7c5b9943ce5476ffd652410b19b4329140708
parent75f0194e8566a43a12155208bbef5474b2aad01b (diff)
Fixing conv.Join to handle non-interface{} arrays
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
-rw-r--r--conv/conv.go47
-rw-r--r--conv/conv_test.go5
2 files changed, 37 insertions, 15 deletions
diff --git a/conv/conv.go b/conv/conv.go
index 464df7dd..38d88683 100644
--- a/conv/conv.go
+++ b/conv/conv.go
@@ -36,6 +36,11 @@ func Join(in interface{}, sep string) string {
var a []interface{}
a, ok = in.([]interface{})
+ if !ok {
+ var err error
+ a, err = interfaceSlice(in)
+ ok = err == nil
+ }
if ok {
b := make([]string, len(a))
for i := range a {
@@ -48,6 +53,18 @@ func Join(in interface{}, sep string) string {
return ""
}
+func interfaceSlice(slice interface{}) ([]interface{}, error) {
+ s := reflect.ValueOf(slice)
+ if s.Kind() != reflect.Slice {
+ return nil, fmt.Errorf("interfaceSlice given a non-slice type %T", s)
+ }
+ ret := make([]interface{}, s.Len())
+ for i := 0; i < s.Len(); i++ {
+ ret[i] = s.Index(i).Interface()
+ }
+ return ret, nil
+}
+
// Has determines whether or not a given object has a property with the given key
func Has(in interface{}, key string) bool {
av := reflect.ValueOf(in)
@@ -61,28 +78,28 @@ func Has(in interface{}, key string) bool {
}
func toString(in interface{}) string {
+ if in == nil {
+ return "nil"
+ }
if s, ok := in.(string); ok {
return s
}
if s, ok := in.(fmt.Stringer); ok {
return s.String()
}
- if i, ok := in.(int); ok {
- return strconv.Itoa(i)
- }
- if u, ok := in.(uint64); ok {
- return strconv.FormatUint(u, 10)
- }
- if f, ok := in.(float64); ok {
- return strconv.FormatFloat(f, 'f', -1, 64)
- }
- if b, ok := in.(bool); ok {
- return strconv.FormatBool(b)
- }
- if in == nil {
- return "nil"
+ val := reflect.Indirect(reflect.ValueOf(in))
+ switch val.Kind() {
+ case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
+ return strconv.FormatInt(val.Int(), 10)
+ case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64:
+ return strconv.FormatUint(val.Uint(), 10)
+ case reflect.Float32, reflect.Float64:
+ return strconv.FormatFloat(val.Float(), 'f', -1, 64)
+ case reflect.Bool:
+ return strconv.FormatBool(val.Bool())
+ default:
+ return fmt.Sprintf("%s", in)
}
- return fmt.Sprintf("%s", in)
}
// MustParseInt - wrapper for strconv.ParseInt that returns 0 in the case of error
diff --git a/conv/conv_test.go b/conv/conv_test.go
index 5150fbcd..aa35fd49 100644
--- a/conv/conv_test.go
+++ b/conv/conv_test.go
@@ -36,6 +36,11 @@ func TestJoin(t *testing.T) {
assert.Equal(t, "foo,\nbar", Join([]interface{}{"foo", "bar"}, ",\n"))
// Join handles all kinds of scalar types too...
assert.Equal(t, "42-18446744073709551615", Join([]interface{}{42, uint64(18446744073709551615)}, "-"))
+ assert.Equal(t, "42,100", Join([]int{42, 100}, ","))
+ assert.Equal(t, "42,100", Join([]int64{42, 100}, ","))
+ assert.Equal(t, "42,100", Join([]uint64{42, 100}, ","))
+ assert.Equal(t, "true,false", Join([]bool{true, false}, ","))
+ assert.Equal(t, "1,2", Join([]float64{1, 2}, ","))
assert.Equal(t, "1,,true,3.14,foo,nil", Join([]interface{}{1, "", true, 3.14, "foo", nil}, ","))
// and best-effort with weird types
assert.Equal(t, "[foo],bar", Join([]interface{}{[]string{"foo"}, "bar"}, ","))