Repository: goccy/go-yaml
Pull request #232 (2021-06-29 14:39:18)

Support sequence indentation
Fix https://github.com/goccy/go-yaml/issues/177

This introduces a new `IndentSequence` boolean encode option, taking encoder indentation value.

Before:
```
A:
- 1
- 2
```
After
```
A:
  - 1
  - 2
```


Patch:
diff --git a/encode.go b/encode.go
index 116999c..33db2bb 100644
--- a/encode.go
+++ b/encode.go
@@ -30,6 +30,7 @@ type Encoder struct {
 	writer                     io.Writer
 	opts                       []EncodeOption
 	indent                     int
+	indentSequence             bool
 	isFlowStyle                bool
 	isJSONStyle                bool
 	useJSONMarshaler           bool
@@ -369,9 +370,13 @@ func (e *Encoder) encodeBool(v bool) ast.Node {
 }
 
 func (e *Encoder) encodeSlice(ctx context.Context, value reflect.Value) (ast.Node, error) {
-	sequence := ast.Sequence(token.New("-", "-", e.pos(e.column)), e.isFlowStyle)
+	column := e.column
+	if e.indentSequence {
+		column += e.indent
+	}
+	sequence := ast.Sequence(token.New("-", "-", e.pos(column)), e.isFlowStyle)
 	for i := 0; i < value.Len(); i++ {
-		node, err := e.encodeValue(ctx, value.Index(i), e.column)
+		node, err := e.encodeValue(ctx, value.Index(i), column)
 		if err != nil {
 			return nil, errors.Wrapf(err, "failed to encode value for slice")
 		}
@@ -381,9 +386,13 @@ func (e *Encoder) encodeSlice(ctx context.Context, value reflect.Value) (ast.Nod
 }
 
 func (e *Encoder) encodeArray(ctx context.Context, value reflect.Value) (ast.Node, error) {
-	sequence := ast.Sequence(token.New("-", "-", e.pos(e.column)), e.isFlowStyle)
+	column := e.column
+	if e.indentSequence {
+		column += e.indent
+	}
+	sequence := ast.Sequence(token.New("-", "-", e.pos(column)), e.isFlowStyle)
 	for i := 0; i < value.Len(); i++ {
-		node, err := e.encodeValue(ctx, value.Index(i), e.column)
+		node, err := e.encodeValue(ctx, value.Index(i), column)
 		if err != nil {
 			return nil, errors.Wrapf(err, "failed to encode value for array")
 		}
diff --git a/option.go b/option.go
index 9c4557f..5dc72c5 100644
--- a/option.go
+++ b/option.go
@@ -105,6 +105,14 @@ func Indent(spaces int) EncodeOption {
 	}
 }
 
+// IndentSequence causes sequence values to be indented the same value as Indent
+func IndentSequence(indent bool) EncodeOption {
+	return func(e *Encoder) error {
+		e.indentSequence = indent
+		return nil
+	}
+}
+
 // Flow encoding by flow style
 func Flow(isFlowStyle bool) EncodeOption {
 	return func(e *Encoder) error {


Test patch:
diff --git a/encode_test.go b/encode_test.go
index 503b95e..b9284bd 100644
--- a/encode_test.go
+++ b/encode_test.go
@@ -123,11 +123,25 @@ func TestEncoder(t *testing.T) {
 			map[string][]string{"v": {"A", "B"}},
 			nil,
 		},
+		{
+			"v:\n  - A\n  - B\n",
+			map[string][]string{"v": {"A", "B"}},
+			[]yaml.EncodeOption{
+				yaml.IndentSequence(true),
+			},
+		},
 		{
 			"v:\n- A\n- B\n",
 			map[string][2]string{"v": {"A", "B"}},
 			nil,
 		},
+		{
+			"v:\n  - A\n  - B\n",
+			map[string][2]string{"v": {"A", "B"}},
+			[]yaml.EncodeOption{
+				yaml.IndentSequence(true),
+			},
+		},
 		{
 			"a: -\n",
 			map[string]string{"a": "-"},
@@ -207,6 +221,21 @@ func TestEncoder(t *testing.T) {
 			},
 			nil,
 		},
+		{
+			"v:\n  - A\n  - 1\n  - B:\n    - 2\n    - 3\n",
+			map[string]interface{}{
+				"v": []interface{}{
+					"A",
+					1,
+					map[string][]int{
+						"B": {2, 3},
+					},
+				},
+			},
+			[]yaml.EncodeOption{
+				yaml.IndentSequence(true),
+			},
+		},
 		{
 			"a:\n  b: c\n",
 			map[string]interface{}{