From 1d13c5f327e5955f589e0007dbea16dade80fd7a Mon Sep 17 00:00:00 2001 From: Yonas Habteab Date: Fri, 29 Mar 2024 17:57:27 +0100 Subject: [PATCH] Preserve defaults for zero initialised structs as well --- decode.go | 12 ++++++++---- decode_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/decode.go b/decode.go index 79117cae..7343a3f0 100644 --- a/decode.go +++ b/decode.go @@ -954,18 +954,22 @@ func (d *Decoder) createDecodedNewValue( return newValue, nil } } + var newValue reflect.Value if node.Type() == ast.NullType { - return reflect.Zero(typ), nil + newValue = reflect.New(typ).Elem() + } else { + newValue = d.createDecodableValue(typ) } - newValue := d.createDecodableValue(typ) for defaultVal.Kind() == reflect.Ptr { defaultVal = defaultVal.Elem() } if defaultVal.IsValid() && defaultVal.Type().AssignableTo(newValue.Type()) { newValue.Set(defaultVal) } - if err := d.decodeValue(ctx, newValue, node); err != nil { - return newValue, errors.Wrapf(err, "failed to decode value") + if node.Type() != ast.NullType { + if err := d.decodeValue(ctx, newValue, node); err != nil { + return newValue, errors.Wrapf(err, "failed to decode value") + } } return newValue, nil } diff --git a/decode_test.go b/decode_test.go index cabfd33c..f2f3fe92 100644 --- a/decode_test.go +++ b/decode_test.go @@ -2906,3 +2906,28 @@ func TestSameNameInineStruct(t *testing.T) { t.Fatalf("failed to decode") } } + +func TestDecoderPreservesDefaultValues(t *testing.T) { + type second struct { + Val string `yaml:"val"` + } + + type test struct { + First string `yaml:"first"` + Defaults second `yaml:"second"` + } + + yml := ` +first: "Test" +second: + # Just some comment here +# val: "default" +` + v := test{Defaults: second{Val: "default"}} + if err := yaml.Unmarshal([]byte(yml), &v); err != nil { + t.Fatal(err) + } + if v.Defaults.Val != "default" { + t.Fatal("decoder doesn't preserve struct defaults") + } +}