func TestDecodeIntermeidateMapsSettable(t *testing.T) {
	type Timestamp struct {
		Seconds int64
		Nanos   int32
	}
	type TsWrapper struct {
		Timestamp *Timestamp
	}
	type TimeWrapper struct {
		Timestamp time.Time
	}
	input := TimeWrapper{
		Timestamp: time.Unix(123456789, 987654),
	}
	expected := TsWrapper{
		Timestamp: &Timestamp{
			Seconds: 123456789,
			Nanos:   987654,
		},
	}
	timePtrType := reflect.TypeOf((*time.Time)(nil))
	mapStrInfType := reflect.TypeOf((map[string]interface{})(nil))
	var actual TsWrapper
	decoder, err := NewDecoder(&DecoderConfig{
		Result: &actual,
		DecodeHook: func(from, to reflect.Type, data interface{}) (interface{}, error) {
			if from == timePtrType && to == mapStrInfType {
				ts := data.(*time.Time)
				nanos := ts.UnixNano()
				seconds := nanos / 1000000000
				nanos = nanos % 1000000000
				return &map[string]interface{}{
					"Seconds": seconds,
					"Nanos":   int32(nanos),
				}, nil
			}
			return data, nil
		},
	})
	if err != nil {
		t.Fatalf("failed to create decoder: %v", err)
	}
	if err := decoder.Decode(&input); err != nil {
		t.Fatalf("failed to decode input: %v", err)
	}
	if !reflect.DeepEqual(expected, actual) {
		t.Fatalf("expected: %#[1]v (%[1]T), got: %#[2]v (%[2]T)", expected, actual)
	}
}
#202 Ensure that intermediate maps in the struct -> struct decode process are settable
and not just the elements within them.
package mapstructure
import (
	"reflect"
	"testing"
	"time"
)
func TestDecode_NilValue(t *testing.T) {
	t.Parallel()
	tests := []struct {
		name       string
		in         interface{}
		target     interface{}
		out        interface{}
		metaKeys   []string
		metaUnused []string
	}{
		{
			"all nil",
			&map[string]interface{}{
				"vfoo":   nil,
				"vother": nil,
			},
			&Map{Vfoo: "foo", Vother: map[string]string{"foo": "bar"}},
			&Map{Vfoo: "", Vother: nil},
			[]string{"Vfoo", "Vother"},
			[]string{},
		},
		{
			"partial nil",
			&map[string]interface{}{
				"vfoo":   "baz",
				"vother": nil,
			},
			&Map{Vfoo: "foo", Vother: map[string]string{"foo": "bar"}},
			&Map{Vfoo: "baz", Vother: nil},
			[]string{"Vfoo", "Vother"},
			[]string{},
		},
		{
			"partial decode",
			&map[string]interface{}{
				"vother": nil,
			},
			&Map{Vfoo: "foo", Vother: map[string]string{"foo": "bar"}},
			&Map{Vfoo: "foo", Vother: nil},
			[]string{"Vother"},
			[]string{},
		},
		{
			"unused values",
			&map[string]interface{}{
				"vbar":   "bar",
				"vfoo":   nil,
				"vother": nil,
			},
			&Map{Vfoo: "foo", Vother: map[string]string{"foo": "bar"}},
			&Map{Vfoo: "", Vother: nil},
			[]string{"Vfoo", "Vother"},
			[]string{"vbar"},
		},
		{
			"map interface all nil",
			&map[interface{}]interface{}{
				"vfoo":   nil,
				"vother": nil,
			},
			&Map{Vfoo: "foo", Vother: map[string]string{"foo": "bar"}},
			&Map{Vfoo: "", Vother: nil},
			[]string{"Vfoo", "Vother"},
			[]string{},
		},
		{
			"map interface partial nil",
			&map[interface{}]interface{}{
				"vfoo":   "baz",
				"vother": nil,
			},
			&Map{Vfoo: "foo", Vother: map[string]string{"foo": "bar"}},
			&Map{Vfoo: "baz", Vother: nil},
			[]string{"Vfoo", "Vother"},
			[]string{},
		},
		{
			"map interface partial decode",
			&map[interface{}]interface{}{
				"vother": nil,
			},
			&Map{Vfoo: "foo", Vother: map[string]string{"foo": "bar"}},
			&Map{Vfoo: "foo", Vother: nil},
			[]string{"Vother"},
			[]string{},
		},
		{
			"map interface unused values",
			&map[interface{}]interface{}{
				"vbar":   "bar",
				"vfoo":   nil,
				"vother": nil,
			},
			&Map{Vfoo: "foo", Vother: map[string]string{"foo": "bar"}},
			&Map{Vfoo: "", Vother: nil},
			[]string{"Vfoo", "Vother"},
			[]string{"vbar"},
		},
	}
	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			config := &DecoderConfig{
				Metadata:   new(Metadata),
				Result:     tc.target,
				ZeroFields: true,
			}
			decoder, err := NewDecoder(config)
			if err != nil {
				t.Fatalf("should not error: %s", err)
			}
			err = decoder.Decode(tc.in)
			if err != nil {
				t.Fatalf("should not error: %s", err)
			}
			if !reflect.DeepEqual(tc.out, tc.target) {
				t.Fatalf("%q: TestDecode_NilValue() expected: %#v, got: %#v", tc.name, tc.out, tc.target)
			}
			if !reflect.DeepEqual(tc.metaKeys, config.Metadata.Keys) {
				t.Fatalf("%q: Metadata.Keys mismatch expected: %#v, got: %#v", tc.name, tc.metaKeys, config.Metadata.Keys)
			}
			if !reflect.DeepEqual(tc.metaUnused, config.Metadata.Unused) {
				t.Fatalf("%q: Metadata.Unused mismatch expected: %#v, got: %#v", tc.name, tc.metaUnused, config.Metadata.Unused)
			}
		})
	}
}
func TestNestedTypePointerWithDefaults(t *testing.T) {
	t.Parallel()
	input := map[string]interface{}{
		"vfoo": "foo",
		"vbar": map[string]interface{}{
			"vstring": "foo",
			"vint":    42,
			"vbool":   true,
		},
	}
	result := NestedPointer{
		Vbar: &Basic{
			Vuint: 42,
		},
	}
	err := Decode(input, &result)
	if err != nil {
		t.Fatalf("got an err: %s", err.Error())
	}
	if result.Vfoo != "foo" {
		t.Errorf("vfoo value should be 'foo': %#v", result.Vfoo)
	}
	if result.Vbar.Vstring != "foo" {
		t.Errorf("vstring value should be 'foo': %#v", result.Vbar.Vstring)
	}
	if result.Vbar.Vint != 42 {
		t.Errorf("vint value should be 42: %#v", result.Vbar.Vint)
	}
	if result.Vbar.Vbool != true {
		t.Errorf("vbool value should be true: %#v", result.Vbar.Vbool)
	}
	if result.Vbar.Vextra != "" {
		t.Errorf("vextra value should be empty: %#v", result.Vbar.Vextra)
	}
	if result.Vbar.Vuint != 42 {
		t.Errorf("vuint value should be 42: %#v", result.Vbar.Vuint)
	}
}
type NestedSlice struct {
	Vfoo   string
	Vbars  []Basic
	Vempty []Basic
}
func TestNestedTypeSliceWithDefaults(t *testing.T) {
	t.Parallel()
	input := map[string]interface{}{
		"vfoo": "foo",
		"vbars": []map[string]interface{}{
			{"vstring": "foo", "vint": 42, "vbool": true},
			{"vint": 42, "vbool": true},
		},
		"vempty": []map[string]interface{}{
			{"vstring": "foo", "vint": 42, "vbool": true},
			{"vint": 42, "vbool": true},
		},
	}
	result := NestedSlice{
		Vbars: []Basic{
			{Vuint: 42},
			{Vstring: "foo"},
		},
	}
	err := Decode(input, &result)
	if err != nil {
		t.Fatalf("got an err: %s", err.Error())
	}
	if result.Vfoo != "foo" {
		t.Errorf("vfoo value should be 'foo': %#v", result.Vfoo)
	}
	if result.Vbars[0].Vstring != "foo" {
		t.Errorf("vstring value should be 'foo': %#v", result.Vbars[0].Vstring)
	}
	if result.Vbars[0].Vuint != 42 {
		t.Errorf("vuint value should be 42: %#v", result.Vbars[0].Vuint)
	}
}
func TestNestedTypeWithDefaults(t *testing.T) {
	t.Parallel()
	input := map[string]interface{}{
		"vfoo": "foo",
		"vbar": map[string]interface{}{
			"vstring": "foo",
			"vint":    42,
			"vbool":   true,
		},
	}
	result := Nested{
		Vbar: Basic{
			Vuint: 42,
		},
	}
	err := Decode(input, &result)
	if err != nil {
		t.Fatalf("got an err: %s", err.Error())
	}
	if result.Vfoo != "foo" {
		t.Errorf("vfoo value should be 'foo': %#v", result.Vfoo)
	}
	if result.Vbar.Vstring != "foo" {
		t.Errorf("vstring value should be 'foo': %#v", result.Vbar.Vstring)
	}
	if result.Vbar.Vint != 42 {
		t.Errorf("vint value should be 42: %#v", result.Vbar.Vint)
	}
	if result.Vbar.Vbool != true {
		t.Errorf("vbool value should be true: %#v", result.Vbar.Vbool)
	}
	if result.Vbar.Vextra != "" {
		t.Errorf("vextra value should be empty: %#v", result.Vbar.Vextra)
	}
	if result.Vbar.Vuint != 42 {
		t.Errorf("vuint value should be 42: %#v", result.Vbar.Vuint)
	}
}
func TestDecodeSliceToEmptySliceWOZeroing(t *testing.T) {
	t.Parallel()
	type TestStruct struct {
		Vfoo []string
	}
	decode := func(m interface{}, rawVal interface{}) error {
		config := &DecoderConfig{
			Metadata:   nil,
			Result:     rawVal,
			ZeroFields: false,
		}
		decoder, err := NewDecoder(config)
		if err != nil {
			return err
		}
		return decoder.Decode(m)
	}
	{
		input := map[string]interface{}{
			"vfoo": []string{"1"},
		}
		result := &TestStruct{}
		err := decode(input, &result)
		if err != nil {
			t.Fatalf("got an err: %s", err.Error())
		}
	}
	{
		input := map[string]interface{}{
			"vfoo": []string{"1"},
		}
		result := &TestStruct{
			Vfoo: []string{},
		}
		err := decode(input, &result)
		if err != nil {
			t.Fatalf("got an err: %s", err.Error())
		}
	}
	{
		input := map[string]interface{}{
			"vfoo": []string{"2", "3"},
		}
		result := &TestStruct{
			Vfoo: []string{"1"},
		}
		err := decode(input, &result)
		if err != nil {
			t.Fatalf("got an err: %s", err.Error())
		}
	}
}
func TestNextSquashMapstructure(t *testing.T) {
	data := &struct {
		Level1 struct {
			Level2 struct {
				Foo string
			} `mapstructure:",squash"`
		} `mapstructure:",squash"`
	}{}
	err := Decode(map[interface{}]interface{}{"foo": "baz"}, &data)
	if err != nil {
		t.Fatalf("should not error: %s", err)
	}
	if data.Level1.Level2.Foo != "baz" {
		t.Fatal("value should be baz")
	}
}
type ImplementsInterfacePointerReceiver struct {
	Name string
}
func (i *ImplementsInterfacePointerReceiver) DoStuff() {}
type ImplementsInterfaceValueReceiver string
func (i ImplementsInterfaceValueReceiver) DoStuff() {}
func TestDecode_DecodeHookInterface(t *testing.T) {
	t.Parallel()
	type Interface interface {
		DoStuff()
	}
	type DecodeIntoInterface struct {
		Test Interface
	}
	testData := map[string]string{"test": "test"}
	stringToPointerInterfaceDecodeHook := func(from, to reflect.Type, data interface{}) (interface{}, error) {
		if from.Kind() != reflect.String {
			return data, nil
		}
		if to != reflect.TypeOf((*Interface)(nil)).Elem() {
			return data, nil
		}
		var impl Interface = &ImplementsInterfacePointerReceiver{data.(string)}
		return impl, nil
	}
	stringToValueInterfaceDecodeHook := func(from, to reflect.Type, data interface{}) (interface{}, error) {
		if from.Kind() != reflect.String {
			return data, nil
		}
		if to != reflect.TypeOf((*Interface)(nil)).Elem() {
			return data, nil
		}
		var impl Interface = ImplementsInterfaceValueReceiver(data.(string))
		return impl, nil
	}
	{
		decodeInto := new(DecodeIntoInterface)
		decoder, _ := NewDecoder(&DecoderConfig{
			DecodeHook: stringToPointerInterfaceDecodeHook,
			Result:     decodeInto,
		})
		err := decoder.Decode(testData)
		if err != nil {
			t.Fatalf("Decode returned error: %s", err)
		}
		expected := &ImplementsInterfacePointerReceiver{"test"}
		if !reflect.DeepEqual(decodeInto.Test, expected) {
			t.Fatalf("expected: %#v (%T), got: %#v (%T)", decodeInto.Test, decodeInto.Test, expected, expected)
		}
	}
	{
		decodeInto := new(DecodeIntoInterface)
		decoder, _ := NewDecoder(&DecoderConfig{
			DecodeHook: stringToValueInterfaceDecodeHook,
			Result:     decodeInto,
		})
		err := decoder.Decode(testData)
		if err != nil {
			t.Fatalf("Decode returned error: %s", err)
		}
		expected := ImplementsInterfaceValueReceiver("test")
		if !reflect.DeepEqual(decodeInto.Test, expected) {
			t.Fatalf("expected: %#v (%T), got: %#v (%T)", decodeInto.Test, decodeInto.Test, expected, expected)
		}
	}
}
func TestDecodeBadDataTypeInSlice(t *testing.T) {
	t.Parallel()
	input := map[string]interface{}{
		"Toto": "titi",
	}
	result := []struct {
		Toto string
	}{}
	if err := Decode(input, &result); err == nil {
		t.Error("An error was expected, got nil")
	}
}