diff --git a/cast.go b/cast.go index 0cfe941..19bea1c 100644 --- a/cast.go +++ b/cast.go @@ -139,6 +139,12 @@ func ToStringMapInt64(i interface{}) map[string]int64 { return v } +// ToStringMapTimeDuration casts an interface to a map[string]time.Duration type. +func ToStringMapTimeDuration(i interface{}) map[string]time.Duration { + v, _ := ToStringMapTimeDurationE(i) + return v +} + // ToStringMap casts an interface to a map[string]interface{} type. func ToStringMap(i interface{}) map[string]interface{} { v, _ := ToStringMapE(i) diff --git a/cast_test.go b/cast_test.go index c254c57..dac77d7 100644 --- a/cast_test.go +++ b/cast_test.go @@ -946,6 +946,48 @@ func TestToStringMapStringE(t *testing.T) { } } +func TestToStringMapTimeDuration(t *testing.T) { + var expectResult = map[string]time.Duration{"key 1": 300000000000, "key 2": 36000000000000, "key 3": 4530918273645} + var stringMapString = map[string]string{"key 1": "5m", "key 2": "10h", "key 3": "1h15m30.918273645s"} + var stringMapInterface = map[string]interface{}{"key 1": "5m", "key 2": "10h", "key 3": "1h15m30.918273645s"} + var interfaceMapString = map[interface{}]string{"key 1": "5m", "key 2": "10h", "key 3": "1h15m30.918273645s"} + var interfaceMapInterface = map[interface{}]interface{}{"key 1": "5m", "key 2": "10h", "key 3": "1h15m30.918273645s"} + var emptyString = "" + + tests := []struct { + input interface{} + expect map[string]time.Duration + iserr bool + }{ + {stringMapString, expectResult, false}, + {stringMapInterface, expectResult, false}, + {interfaceMapString, expectResult, false}, + {interfaceMapInterface, expectResult, false}, + + // errors + {nil, nil, true}, + {testing.T{}, nil, true}, + {emptyString, nil, true}, + } + + for i, test := range tests { + errmsg := fmt.Sprintf("i = %d", i) // assert helper message + + v, err := ToStringMapTimeDurationE(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 = ToStringMapTimeDuration(test.input) + assert.Equal(t, test.expect, v, errmsg) + } +} + func TestToBoolSliceE(t *testing.T) { tests := []struct { input interface{} diff --git a/caste.go b/caste.go index c04af6a..8f91355 100644 --- a/caste.go +++ b/caste.go @@ -1078,6 +1078,36 @@ func ToStringMapInt64E(i interface{}) (map[string]int64, error) { return m, nil } +// ToStringMapTimeDurationE casts an interface to a map[string]time.Duration type. +func ToStringMapTimeDurationE(i interface{}) (map[string]time.Duration, error) { + var m = map[string]time.Duration{} + + switch v := i.(type) { + case map[string]string: + for k, val := range v { + m[ToString(k)] = ToDuration(val) + } + return m, nil + case map[string]interface{}: + for k, val := range v { + m[ToString(k)] = ToDuration(val) + } + return m, nil + case map[interface{}]string: + for k, val := range v { + m[ToString(k)] = ToDuration(val) + } + return m, nil + case map[interface{}]interface{}: + for k, val := range v { + m[ToString(k)] = ToDuration(val) + } + return m, nil + default: + return m, fmt.Errorf("unable to cast %#v of type %T to map[string]time.Duration", i, i) + } +} + // ToSliceE casts an interface to a []interface{} type. func ToSliceE(i interface{}) ([]interface{}, error) { var s []interface{}