diff --git a/cast.go b/cast.go index dc504b4..8b8c208 100644 --- a/cast.go +++ b/cast.go @@ -151,3 +151,9 @@ func ToIntSlice(i interface{}) []int { v, _ := ToIntSliceE(i) return v } + +// ToDurationSlice casts an interface to a []time.Duration type. +func ToDurationSlice(i interface{}) []time.Duration { + v, _ := ToDurationSliceE(i) + return v +} diff --git a/cast_test.go b/cast_test.go index 2bb8c5f..404fe76 100644 --- a/cast_test.go +++ b/cast_test.go @@ -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) { tests := []struct { input interface{} diff --git a/caste.go b/caste.go index 4e75f64..81511fe 100644 --- a/caste.go +++ b/caste.go @@ -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 // predefined list of formats. If no suitable format is found, an error is // returned.