Properly decode each slice type as well
diff --git a/mapstructure.go b/mapstructure.go index 1233c73..ec0941e 100644 --- a/mapstructure.go +++ b/mapstructure.go
@@ -100,7 +100,28 @@ func decodeSlice(name string, data interface{}, val reflect.Value) error { dataVal := reflect.Indirect(reflect.ValueOf(data)) - val.Set(dataVal) + valType := val.Type() + valElemType := valType.Elem() + + // TODO: Error checking to make sure data is an array/slice type + + // Make a new slice to hold our result, same size as the original data. + sliceType := reflect.SliceOf(valElemType) + valSlice := reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len()) + + for i := 0; i < dataVal.Len(); i++ { + currentData := dataVal.Index(i).Interface() + currentField := valSlice.Index(i) + + fieldName := fmt.Sprintf("%s[%d]", name, i) + if err := decode(fieldName, currentData, currentField); err != nil { + return err + } + } + + // Finally, set the value to the slice we built up + val.Set(valSlice) + return nil }
diff --git a/mapstructure_test.go b/mapstructure_test.go index 7070dd4..df98537 100644 --- a/mapstructure_test.go +++ b/mapstructure_test.go
@@ -24,6 +24,10 @@ Vbar []string } +type SliceOfStruct struct { + Value []Basic +} + func TestBasicTypes(t *testing.T) { t.Parallel() @@ -199,6 +203,37 @@ testSliceInput(t, inputStringSlicePointer, outputStringSlice) } +func TestSliceOfStruct(t *testing.T) { + t.Parallel() + + input := map[string]interface{}{ + "value": []map[string]interface{}{ + {"vstring": "one"}, + {"vstring": "two"}, + }, + } + + var result SliceOfStruct + err := Decode(input, &result) + if err != nil { + t.Errorf("got unexpected error: %s", err) + t.FailNow() + } + + if len(result.Value) != 2 { + t.Errorf("expected two values, got %d", len(result.Value)) + t.FailNow() + } + + if result.Value[0].Vstring != "one" { + t.Errorf("first value should be 'one', got: %s", result.Value[0].Vstring) + } + + if result.Value[1].Vstring != "two" { + t.Errorf("second value should be 'two', got: %s", result.Value[1].Vstring) + } +} + func TestInvalidType(t *testing.T) { t.Parallel()