From 137dbf920d3e6cac21392a833d3d13a3ad29e7b2 Mon Sep 17 00:00:00 2001 From: zoncoen Date: Wed, 13 Sep 2023 16:56:06 +0900 Subject: [PATCH] fix: skip encoding an inline field if it is null --- encode.go | 4 ++++ encode_test.go | 47 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/encode.go b/encode.go index 7d8d81e0..3b9b2981 100644 --- a/encode.go +++ b/encode.go @@ -823,6 +823,10 @@ func (e *Encoder) encodeStruct(ctx context.Context, value reflect.Value, column } mapNode, ok := value.(ast.MapNode) if !ok { + // if an inline field is null, skip encoding it + if _, ok := value.(*ast.NullNode); ok { + continue + } return nil, xerrors.Errorf("inline value is must be map or struct type") } mapIter := mapNode.MapRange() diff --git a/encode_test.go b/encode_test.go index 74b1aa59..c052e5a3 100644 --- a/encode_test.go +++ b/encode_test.go @@ -16,8 +16,10 @@ import ( "github.com/goccy/go-yaml/ast" ) -var zero = 0 -var emptyStr = "" +var ( + zero = 0 + emptyStr = "" +) func TestEncoder(t *testing.T) { tests := []struct { @@ -643,12 +645,12 @@ func TestEncoder(t *testing.T) { // time value { "v: 0001-01-01T00:00:00Z\n", - map[string]time.Time{"v": time.Time{}}, + map[string]time.Time{"v": {}}, nil, }, { "v: 0001-01-01T00:00:00Z\n", - map[string]*time.Time{"v": &time.Time{}}, + map[string]*time.Time{"v": {}}, nil, }, { @@ -980,6 +982,30 @@ c: true } } +func TestEncoder_InlineNil(t *testing.T) { + type base struct { + A int + B string + } + var buf bytes.Buffer + enc := yaml.NewEncoder(&buf) + if err := enc.Encode(struct { + *base `yaml:",inline"` + C bool + }{ + C: true, + }); err != nil { + t.Fatalf("%+v", err) + } + expect := ` +c: true +` + actual := "\n" + buf.String() + if expect != actual { + t.Fatalf("inline marshal error: expect=[%s] actual=[%s]", expect, actual) + } +} + func TestEncoder_Flow(t *testing.T) { var buf bytes.Buffer enc := yaml.NewEncoder(&buf, yaml.Flow(true)) @@ -1014,7 +1040,7 @@ func TestEncoder_FlowRecursive(t *testing.T) { M map[string][]int `yaml:",flow"` } v.M = map[string][]int{ - "test": []int{1, 2, 3}, + "test": {1, 2, 3}, } var buf bytes.Buffer if err := yaml.NewEncoder(&buf).Encode(v); err != nil { @@ -1311,6 +1337,7 @@ func (t *tMarshal) MarshalYAML() ([]byte, error) { } return buf.Bytes(), nil } + func Test_Marshaler(t *testing.T) { const expected = `- hello-world ` @@ -1365,10 +1392,12 @@ type FastMarshaler struct { A string B int } -type TextMarshaler int64 -type TextMarshalerContainer struct { - Field TextMarshaler `yaml:"field"` -} +type ( + TextMarshaler int64 + TextMarshalerContainer struct { + Field TextMarshaler `yaml:"field"` + } +) func (v SlowMarshaler) MarshalYAML() ([]byte, error) { var buf bytes.Buffer