mirror of
https://github.com/goccy/go-yaml.git
synced 2025-12-08 06:09:57 +00:00
encodeMap() error handling and TestEncoder_UnmarshallableTypes() (#674)
* encodeMap() error handling and TestEncoder_UnmarshallableTypes() * more TestEncoder_UnmarshallableTypes test cases
This commit is contained in:
parent
944206aba5
commit
96713633e1
2 changed files with 80 additions and 4 deletions
|
|
@ -492,7 +492,7 @@ func (e *Encoder) encodeValue(ctx context.Context, v reflect.Value, column int)
|
||||||
if value := e.encodePtrAnchor(v, column); value != nil {
|
if value := e.encodePtrAnchor(v, column); value != nil {
|
||||||
return value, nil
|
return value, nil
|
||||||
}
|
}
|
||||||
return e.encodeMap(ctx, v, column), nil
|
return e.encodeMap(ctx, v, column)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unknown value type %s", v.Type().String())
|
return nil, fmt.Errorf("unknown value type %s", v.Type().String())
|
||||||
}
|
}
|
||||||
|
|
@ -684,7 +684,7 @@ func (e *Encoder) isTagAndMapNode(node ast.Node) bool {
|
||||||
return ok && e.isMapNode(tn.Value)
|
return ok && e.isMapNode(tn.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Encoder) encodeMap(ctx context.Context, value reflect.Value, column int) ast.Node {
|
func (e *Encoder) encodeMap(ctx context.Context, value reflect.Value, column int) (ast.Node, error) {
|
||||||
node := ast.Mapping(token.New("", "", e.pos(column)), e.isFlowStyle)
|
node := ast.Mapping(token.New("", "", e.pos(column)), e.isFlowStyle)
|
||||||
keys := make([]interface{}, len(value.MapKeys()))
|
keys := make([]interface{}, len(value.MapKeys()))
|
||||||
for i, k := range value.MapKeys() {
|
for i, k := range value.MapKeys() {
|
||||||
|
|
@ -698,7 +698,7 @@ func (e *Encoder) encodeMap(ctx context.Context, value reflect.Value, column int
|
||||||
v := value.MapIndex(k)
|
v := value.MapIndex(k)
|
||||||
value, err := e.encodeValue(ctx, v, column)
|
value, err := e.encodeValue(ctx, v, column)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil, err
|
||||||
}
|
}
|
||||||
if e.isMapNode(value) {
|
if e.isMapNode(value) {
|
||||||
value.AddColumn(e.indentNum)
|
value.AddColumn(e.indentNum)
|
||||||
|
|
@ -724,7 +724,7 @@ func (e *Encoder) encodeMap(ctx context.Context, value reflect.Value, column int
|
||||||
))
|
))
|
||||||
e.setSmartAnchor(vRef, keyText)
|
e.setSmartAnchor(vRef, keyText)
|
||||||
}
|
}
|
||||||
return node
|
return node, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsZeroer is used to check whether an object is zero to determine
|
// IsZeroer is used to check whether an object is zero to determine
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/goccy/go-yaml"
|
"github.com/goccy/go-yaml"
|
||||||
"github.com/goccy/go-yaml/ast"
|
"github.com/goccy/go-yaml/ast"
|
||||||
|
|
@ -1345,6 +1346,81 @@ func TestEncoder_MultipleDocuments(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEncoder_UnmarshallableTypes(t *testing.T) {
|
||||||
|
for _, test := range []struct {
|
||||||
|
desc string
|
||||||
|
input any
|
||||||
|
expectedErr string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "channel",
|
||||||
|
input: make(chan int),
|
||||||
|
expectedErr: "unknown value type chan int",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "function",
|
||||||
|
input: func() {},
|
||||||
|
expectedErr: "unknown value type func()",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "complex number",
|
||||||
|
input: complex(10, 11),
|
||||||
|
expectedErr: "unknown value type complex128",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "unsafe pointer",
|
||||||
|
input: unsafe.Pointer(&struct{}{}),
|
||||||
|
expectedErr: "unknown value type unsafe.Pointer",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "uintptr",
|
||||||
|
input: uintptr(0x1234),
|
||||||
|
expectedErr: "unknown value type uintptr",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "map with channel",
|
||||||
|
input: map[string]any{"key": make(chan string)},
|
||||||
|
expectedErr: "unknown value type chan string",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "nested map with func",
|
||||||
|
input: map[string]any{
|
||||||
|
"a": map[string]any{
|
||||||
|
"b": func(_ string) {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedErr: "unknown value type func(string)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "slice with channel",
|
||||||
|
input: []any{make(chan bool)},
|
||||||
|
expectedErr: "unknown value type chan bool",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "nested slice with complex number",
|
||||||
|
input: []any{[]any{complex(10, 11)}},
|
||||||
|
expectedErr: "unknown value type complex128",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "struct with unsafe pointer",
|
||||||
|
input: struct {
|
||||||
|
Field unsafe.Pointer `yaml:"field"`
|
||||||
|
}{},
|
||||||
|
expectedErr: "unknown value type unsafe.Pointer",
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err := yaml.NewEncoder(&buf).Encode(test.input)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("expect error:\n%s\nbut got none\n", test.expectedErr)
|
||||||
|
} else if err.Error() != test.expectedErr {
|
||||||
|
t.Errorf("expect error:\n%s\nactual\n%s\n", test.expectedErr, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func ExampleMarshal_node() {
|
func ExampleMarshal_node() {
|
||||||
type T struct {
|
type T struct {
|
||||||
Text ast.Node `yaml:"text"`
|
Text ast.Node `yaml:"text"`
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue