Support decoding slices
diff --git a/mapstructure.go b/mapstructure.go index 536e8c2..1233c73 100644 --- a/mapstructure.go +++ b/mapstructure.go
@@ -51,6 +51,8 @@ return decodeStruct(name, data, val) case reflect.Map: return decodeMap(name, data, val) + case reflect.Slice: + return decodeSlice(name, data, val) } // If we reached this point then we weren't able to decode it @@ -96,6 +98,12 @@ return nil } +func decodeSlice(name string, data interface{}, val reflect.Value) error { + dataVal := reflect.Indirect(reflect.ValueOf(data)) + val.Set(dataVal) + return nil +} + func decodeStruct(name string, data interface{}, val reflect.Value) error { dataVal := reflect.Indirect(reflect.ValueOf(data)) dataValKind := dataVal.Kind()
diff --git a/mapstructure_test.go b/mapstructure_test.go index d87d151..7070dd4 100644 --- a/mapstructure_test.go +++ b/mapstructure_test.go
@@ -19,6 +19,11 @@ Vbar Basic } +type Slice struct { + Vfoo string + Vbar []string +} + func TestBasicTypes(t *testing.T) { t.Parallel() @@ -172,6 +177,28 @@ } } +func TestSlice(t *testing.T) { + t.Parallel() + + inputStringSlice := map[string]interface{}{ + "vfoo": "foo", + "vbar": []string{"foo", "bar", "baz"}, + } + + inputStringSlicePointer := map[string]interface{}{ + "vfoo": "foo", + "vbar": &[]string{"foo", "bar", "baz"}, + } + + outputStringSlice := &Slice{ + "foo", + []string{"foo", "bar", "baz"}, + } + + testSliceInput(t, inputStringSlice, outputStringSlice) + testSliceInput(t, inputStringSlicePointer, outputStringSlice) +} + func TestInvalidType(t *testing.T) { t.Parallel() @@ -219,3 +246,33 @@ t.Errorf("got unexpected error: %s", err) } } + +func testSliceInput(t *testing.T, input map[string]interface{}, expected *Slice) { + var result Slice + err := Decode(input, &result) + if err != nil { + t.Errorf("got error: %s", err) + t.FailNow() + } + + if result.Vfoo != expected.Vfoo { + t.Errorf("Vfoo expected '%s', got '%s'", expected.Vfoo, result.Vfoo) + } + + if result.Vbar == nil { + t.Errorf("Vbar a slice, got '%#v'", result.Vbar) + t.FailNow() + } + + if len(result.Vbar) != len(expected.Vbar) { + t.Errorf("Vbar length should be %d, got %d", len(expected.Vbar), len(result.Vbar)) + } + + for i, v := range result.Vbar { + if v != expected.Vbar[i] { + t.Errorf( + "Vbar[%d] should be '%#v', got '%#v'", + i, expected.Vbar[i], v) + } + } +}