@@ -151,3 +151,9 @@ func ToIntSlice(i interface{}) []int { | |||||
v, _ := ToIntSliceE(i) | v, _ := ToIntSliceE(i) | ||||
return v | return v | ||||
} | } | ||||
// ToDurationSlice casts an interface to a []time.Duration type. | |||||
func ToDurationSlice(i interface{}) []time.Duration { | |||||
v, _ := ToDurationSliceE(i) | |||||
return v | |||||
} |
@@ -975,6 +975,38 @@ func TestToStringSliceE(t *testing.T) { | |||||
} | } | ||||
} | } | ||||
func TestToDurationSliceE(t *testing.T) { | |||||
tests := []struct { | |||||
input interface{} | |||||
expect []time.Duration | |||||
iserr bool | |||||
}{ | |||||
{[]string{"1s", "1m"}, []time.Duration{time.Second, time.Minute}, false}, | |||||
{[]int{1, 2}, []time.Duration{1, 2}, false}, | |||||
{[]interface{}{1, 3}, []time.Duration{1, 3}, false}, | |||||
// errors | |||||
{nil, nil, true}, | |||||
{testing.T{}, nil, true}, | |||||
} | |||||
for i, test := range tests { | |||||
errmsg := fmt.Sprintf("i = %d", i) // assert helper message | |||||
v, err := ToDurationSliceE(test.input) | |||||
if test.iserr { | |||||
assert.Error(t, err, errmsg) | |||||
continue | |||||
} | |||||
assert.NoError(t, err, errmsg) | |||||
assert.Equal(t, test.expect, v, errmsg) | |||||
// Non-E test | |||||
v = ToDurationSlice(test.input) | |||||
assert.Equal(t, test.expect, v, errmsg) | |||||
} | |||||
} | |||||
func TestToBoolE(t *testing.T) { | func TestToBoolE(t *testing.T) { | ||||
tests := []struct { | tests := []struct { | ||||
input interface{} | input interface{} | ||||
@@ -1077,6 +1077,35 @@ func ToIntSliceE(i interface{}) ([]int, error) { | |||||
} | } | ||||
} | } | ||||
// ToDurationSliceE casts an interface to a []time.Duration type. | |||||
func ToDurationSliceE(i interface{}) ([]time.Duration, error) { | |||||
if i == nil { | |||||
return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i) | |||||
} | |||||
switch v := i.(type) { | |||||
case []time.Duration: | |||||
return v, nil | |||||
} | |||||
kind := reflect.TypeOf(i).Kind() | |||||
switch kind { | |||||
case reflect.Slice, reflect.Array: | |||||
s := reflect.ValueOf(i) | |||||
a := make([]time.Duration, s.Len()) | |||||
for j := 0; j < s.Len(); j++ { | |||||
val, err := ToDurationE(s.Index(j).Interface()) | |||||
if err != nil { | |||||
return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i) | |||||
} | |||||
a[j] = val | |||||
} | |||||
return a, nil | |||||
default: | |||||
return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i) | |||||
} | |||||
} | |||||
// StringToDate attempts to parse a string into a time.Time type using a | // StringToDate attempts to parse a string into a time.Time type using a | ||||
// predefined list of formats. If no suitable format is found, an error is | // predefined list of formats. If no suitable format is found, an error is | ||||
// returned. | // returned. | ||||