From 7bbefaa2a042b74aa163cb995803735a14b2527c Mon Sep 17 00:00:00 2001 From: Joe Kralicky Date: Wed, 20 Apr 2022 13:17:59 -0400 Subject: [PATCH] Fix squash not working when decoder config option is set and squash struct tags are present --- mapstructure.go | 2 +- mapstructure_test.go | 47 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/mapstructure.go b/mapstructure.go index 6b81b00..f941dd5 100644 --- a/mapstructure.go +++ b/mapstructure.go @@ -920,7 +920,7 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re } // If "squash" is specified in the tag, we squash the field down. - squash = !squash && strings.Index(tagValue[index+1:], "squash") != -1 + squash = squash || strings.Index(tagValue[index+1:], "squash") != -1 if squash { // When squashing, the embedded type can be a pointer to a struct. if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct { diff --git a/mapstructure_test.go b/mapstructure_test.go index a78e77a..1ec32e5 100644 --- a/mapstructure_test.go +++ b/mapstructure_test.go @@ -812,6 +812,53 @@ func TestDecodeFrom_EmbeddedSquashConfig(t *testing.T) { } } +func TestDecodeFrom_EmbeddedSquashConfig_WithTags(t *testing.T) { + t.Parallel() + + var v interface{} + var ok bool + + input := EmbeddedSquash{ + Basic: Basic{ + Vstring: "foo", + }, + Vunique: "bar", + } + + result := map[string]interface{}{} + config := &DecoderConfig{ + Squash: true, + Result: &result, + } + decoder, err := NewDecoder(config) + if err != nil { + t.Fatalf("got an err: %s", err.Error()) + } + + err = decoder.Decode(input) + if err != nil { + t.Fatalf("got an err: %s", err.Error()) + } + + if _, ok = result["Basic"]; ok { + t.Error("basic should not be present in map") + } + + v, ok = result["Vstring"] + if !ok { + t.Error("vstring should be present in map") + } else if !reflect.DeepEqual(v, "foo") { + t.Errorf("vstring value should be 'foo': %#v", v) + } + + v, ok = result["Vunique"] + if !ok { + t.Error("vunique should be present in map") + } else if !reflect.DeepEqual(v, "bar") { + t.Errorf("vunique value should be 'bar': %#v", v) + } +} + func TestDecode_SquashOnNonStructType(t *testing.T) { t.Parallel()