diff --git a/encode.go b/encode.go index 7b4ba56..f6f8d6e 100644 --- a/encode.go +++ b/encode.go @@ -405,6 +405,9 @@ func (e *Encoder) isNeedQuoted(v string) bool { if e.useLiteralStyleIfMultiline && strings.ContainsAny(v, "\n\r") { return false } + if e.isFlowStyle && strings.ContainsAny(v, `]},'"`) { + return true + } if token.IsNeedQuoted(v) { return true } @@ -623,19 +626,18 @@ func (e *Encoder) encodeStruct(ctx context.Context, value reflect.Value, column // omit encoding continue } - value, err := e.encodeValue(ctx, fieldValue, column) + ve := e + if !e.isFlowStyle && structField.IsFlow { + ve = &Encoder{} + *ve = *e + ve.isFlowStyle = true + } + value, err := ve.encodeValue(ctx, fieldValue, column) if err != nil { return nil, errors.Wrapf(err, "failed to encode value") } - if m, ok := value.(*ast.MappingNode); ok { - if !e.isFlowStyle && structField.IsFlow { - m.SetIsFlowStyle(true) - } + if _, ok := value.(*ast.MappingNode); ok { value.AddColumn(e.indent) - } else if s, ok := value.(*ast.SequenceNode); ok { - if !e.isFlowStyle && structField.IsFlow { - s.SetIsFlowStyle(true) - } } key := e.encodeString(structField.RenderName, column) switch { diff --git a/encode_test.go b/encode_test.go index 0df0bca..bf7ba48 100644 --- a/encode_test.go +++ b/encode_test.go @@ -548,6 +548,88 @@ func TestEncoder(t *testing.T) { }{struct{ B, D string }{"c", "e"}}, nil, }, + // Quoting in flow mode + { + `a: [b, "c,d", e]` + "\n", + struct { + A []string `yaml:"a,flow"` + }{[]string{"b", "c,d", "e"}}, + []yaml.EncodeOption{ + yaml.UseSingleQuote(false), + }, + }, + { + `a: [b, "c]", d]` + "\n", + struct { + A []string `yaml:"a,flow"` + }{[]string{"b", "c]", "d"}}, + []yaml.EncodeOption{ + yaml.UseSingleQuote(false), + }, + }, + { + `a: [b, "c}", d]` + "\n", + struct { + A []string `yaml:"a,flow"` + }{[]string{"b", "c}", "d"}}, + []yaml.EncodeOption{ + yaml.UseSingleQuote(false), + }, + }, + { + `a: [b, "c\"", d]` + "\n", + struct { + A []string `yaml:"a,flow"` + }{[]string{"b", `c"`, "d"}}, + []yaml.EncodeOption{ + yaml.UseSingleQuote(false), + }, + }, + { + `a: [b, "c'", d]` + "\n", + struct { + A []string `yaml:"a,flow"` + }{[]string{"b", "c'", "d"}}, + []yaml.EncodeOption{ + yaml.UseSingleQuote(false), + }, + }, + // No quoting in non-flow mode + { + "a:\n- b\n- c,d\n- e\n", + struct { + A []string `yaml:"a"` + }{[]string{"b", "c,d", "e"}}, + nil, + }, + { + `a: [b, "c]", d]` + "\n", + struct { + A []string `yaml:"a,flow"` + }{[]string{"b", "c]", "d"}}, + nil, + }, + { + `a: [b, "c}", d]` + "\n", + struct { + A []string `yaml:"a,flow"` + }{[]string{"b", "c}", "d"}}, + nil, + }, + { + `a: [b, "c\"", d]` + "\n", + struct { + A []string `yaml:"a,flow"` + }{[]string{"b", `c"`, "d"}}, + nil, + }, + { + `a: [b, "c'", d]` + "\n", + struct { + A []string `yaml:"a,flow"` + }{[]string{"b", "c'", "d"}}, + nil, + }, // Multi bytes {