mirror of
https://github.com/goccy/go-yaml.git
synced 2025-10-27 03:14:22 +00:00
Add Flow option for Encoder
This commit is contained in:
parent
5e642017ee
commit
e4be76e5f8
3 changed files with 49 additions and 9 deletions
21
encode.go
21
encode.go
|
|
@ -28,6 +28,7 @@ type Encoder struct {
|
|||
writer io.Writer
|
||||
opts []EncodeOption
|
||||
indent int
|
||||
isFlowStyle bool
|
||||
anchorPtrToNameMap map[uintptr]string
|
||||
|
||||
line int
|
||||
|
|
@ -64,6 +65,11 @@ func (e *Encoder) Close() error {
|
|||
//
|
||||
// See the documentation for Marshal for details about the conversion of Go values to YAML.
|
||||
func (e *Encoder) Encode(v interface{}) error {
|
||||
for _, opt := range e.opts {
|
||||
if err := opt(e); err != nil {
|
||||
return errors.Wrapf(err, "failed to run option for encoder")
|
||||
}
|
||||
}
|
||||
node, err := e.encodeValue(reflect.ValueOf(v), 1)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to encode value")
|
||||
|
|
@ -225,10 +231,7 @@ func (e *Encoder) encodeBool(v bool) ast.Node {
|
|||
}
|
||||
|
||||
func (e *Encoder) encodeSlice(value reflect.Value) (ast.Node, error) {
|
||||
sequence := &ast.SequenceNode{
|
||||
Start: token.New("-", "-", e.pos(e.column)),
|
||||
Values: []ast.Node{},
|
||||
}
|
||||
sequence := ast.Sequence(token.New("-", "-", e.pos(e.column)), e.isFlowStyle)
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
node, err := e.encodeValue(value.Index(i), e.column)
|
||||
if err != nil {
|
||||
|
|
@ -259,7 +262,7 @@ func (e *Encoder) encodeMapItem(item MapItem, column int) (*ast.MappingValueNode
|
|||
}
|
||||
|
||||
func (e *Encoder) encodeMapSlice(value MapSlice, column int) (ast.Node, error) {
|
||||
node := ast.Mapping(token.New("", "", e.pos(column)), false)
|
||||
node := ast.Mapping(token.New("", "", e.pos(column)), e.isFlowStyle)
|
||||
for _, item := range value {
|
||||
value, err := e.encodeMapItem(item, column)
|
||||
if err != nil {
|
||||
|
|
@ -271,7 +274,7 @@ func (e *Encoder) encodeMapSlice(value MapSlice, column int) (ast.Node, error) {
|
|||
}
|
||||
|
||||
func (e *Encoder) encodeMap(value reflect.Value, column int) ast.Node {
|
||||
node := ast.Mapping(token.New("", "", e.pos(column)), false)
|
||||
node := ast.Mapping(token.New("", "", e.pos(column)), e.isFlowStyle)
|
||||
keys := []string{}
|
||||
for _, k := range value.MapKeys() {
|
||||
keys = append(keys, k.Interface().(string))
|
||||
|
|
@ -345,7 +348,7 @@ func (e *Encoder) isZeroValue(v reflect.Value) bool {
|
|||
}
|
||||
|
||||
func (e *Encoder) encodeStruct(value reflect.Value, column int) (ast.Node, error) {
|
||||
node := ast.Mapping(token.New("", "", e.pos(column)), false)
|
||||
node := ast.Mapping(token.New("", "", e.pos(column)), e.isFlowStyle)
|
||||
structType := value.Type()
|
||||
structFieldMap, err := structFieldMap(structType)
|
||||
if err != nil {
|
||||
|
|
@ -367,7 +370,7 @@ func (e *Encoder) encodeStruct(value reflect.Value, column int) (ast.Node, error
|
|||
return nil, errors.Wrapf(err, "failed to encode value")
|
||||
}
|
||||
if m, ok := value.(*ast.MappingNode); ok {
|
||||
if structField.IsFlow {
|
||||
if !e.isFlowStyle && structField.IsFlow {
|
||||
m.IsFlowStyle = true
|
||||
}
|
||||
for _, value := range m.Values {
|
||||
|
|
@ -375,7 +378,7 @@ func (e *Encoder) encodeStruct(value reflect.Value, column int) (ast.Node, error
|
|||
value.Value.GetToken().Position.Column += e.indent
|
||||
}
|
||||
} else if s, ok := value.(*ast.SequenceNode); ok {
|
||||
if structField.IsFlow {
|
||||
if !e.isFlowStyle && structField.IsFlow {
|
||||
s.IsFlowStyle = true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -495,6 +495,35 @@ c: true
|
|||
}
|
||||
}
|
||||
|
||||
func TestEncoder_Flow(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
enc := yaml.NewEncoder(&buf, yaml.Flow(true))
|
||||
var v struct {
|
||||
A int
|
||||
B string
|
||||
C struct {
|
||||
D int
|
||||
E string
|
||||
}
|
||||
F []int
|
||||
}
|
||||
v.A = 1
|
||||
v.B = "hello"
|
||||
v.C.D = 3
|
||||
v.C.E = "world"
|
||||
v.F = []int{1, 2}
|
||||
if err := enc.Encode(v); err != nil {
|
||||
t.Fatalf("%+v", err)
|
||||
}
|
||||
expect := `
|
||||
{a: 1, b: hello, c: {d: 3, e: world}, f: [1, 2]}
|
||||
`
|
||||
actual := "\n" + buf.String()
|
||||
if expect != actual {
|
||||
t.Fatalf("flow style marshal error: expect=[%s] actual=[%s]", expect, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func Example_Marshal_ExplicitAnchorAlias() {
|
||||
type T struct {
|
||||
A int
|
||||
|
|
|
|||
|
|
@ -55,3 +55,11 @@ func Indent(spaces int) EncodeOption {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Flow encoding by flow style
|
||||
func Flow(isFlowStyle bool) EncodeOption {
|
||||
return func(e *Encoder) error {
|
||||
e.isFlowStyle = isFlowStyle
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue