diff --git a/config/value.go b/config/value.go index 7c028d44b..d31bd86a4 100644 --- a/config/value.go +++ b/config/value.go @@ -24,6 +24,8 @@ type Value interface { Float() (float64, error) String() (string, error) Duration() (time.Duration, error) + Slice() ([]Value, error) + Map() (map[string]Value, error) Scan(interface{}) error Load() interface{} Store(interface{}) @@ -59,6 +61,32 @@ func (v *atomicValue) Int() (int64, error) { return 0, fmt.Errorf("type assert to %v failed", reflect.TypeOf(v.Load())) } +func (v *atomicValue) Slice() ([]Value, error) { + if vals, ok := v.Load().([]interface{}); ok { + var slices []Value + for _, val := range vals { + a := &atomicValue{} + a.Store(val) + slices = append(slices, a) + } + return slices, nil + } + return nil, fmt.Errorf("type assert to %v failed", reflect.TypeOf(v.Load())) +} + +func (v *atomicValue) Map() (map[string]Value, error) { + if vals, ok := v.Load().(map[string]interface{}); ok { + m := make(map[string]Value) + for key, val := range vals { + a := &atomicValue{} + a.Store(val) + m[key] = a + } + return m, nil + } + return nil, fmt.Errorf("type assert to %v failed", reflect.TypeOf(v.Load())) +} + func (v *atomicValue) Float() (float64, error) { switch val := v.Load().(type) { case float64: @@ -122,3 +150,5 @@ func (v errValue) String() (string, error) { return "", v.err } func (v errValue) Scan(interface{}) error { return v.err } func (v errValue) Load() interface{} { return nil } func (v errValue) Store(interface{}) {} +func (v errValue) Slice() ([]Value, error) { return nil, v.err } +func (v errValue) Map() (map[string]Value, error) { return nil, v.err } diff --git a/config/value_test.go b/config/value_test.go index acc754e0d..dcec2a831 100644 --- a/config/value_test.go +++ b/config/value_test.go @@ -120,6 +120,40 @@ func Test_atomicValue_Duration(t *testing.T) { } } +func Test_atomicValue_Slice(t *testing.T) { + vlist := []interface{}{int64(5)} + v := atomicValue{} + v.Store(vlist) + slices, err := v.Slice() + assert.NoError(t, err) + for _, v := range slices { + b, err := v.Duration() + assert.NoError(t, err) + assert.Equal(t, time.Duration(5), b) + } +} + +func Test_atomicValue_Map(t *testing.T) { + vlist := make(map[string]interface{}) + vlist["5"] = int64(5) + vlist["text"] = "text" + v := atomicValue{} + v.Store(vlist) + m, err := v.Map() + assert.NoError(t, err) + for k, v := range m { + if k == "5" { + b, err := v.Duration() + assert.NoError(t, err) + assert.Equal(t, time.Duration(5), b) + } else { + b, err := v.String() + assert.NoError(t, err) + assert.Equal(t, "text", b) + } + } +} + func Test_atomicValue_Scan(t *testing.T) { var err error v := atomicValue{}