fix(encode): keep a []any of tables in the value-array form
Assisted-by: GLM 5.3
This commit is contained in:
@@ -71,6 +71,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
cannot be carried verbatim by the literal form: a run of three single quotes,
|
cannot be carried verbatim by the literal form: a run of three single quotes,
|
||||||
a control character, or a lone carriage return. Such values previously
|
a control character, or a lone carriage return. Such values previously
|
||||||
produced output that did not re-parse.
|
produced output that did not re-parse.
|
||||||
|
- A `[]any` holding only tables marshals in the value-array form with inline
|
||||||
|
tables, keeping the type `Parse` produces for such an array. It previously
|
||||||
|
took the `[[header]]` form, so a round-trip changed the value's type from
|
||||||
|
`[]any` to `[]map[string]any`.
|
||||||
- Decoding into a `uint` destination checks the type's platform width instead
|
- Decoding into a `uint` destination checks the type's platform width instead
|
||||||
of only the fixed widths, so a 32-bit `uint` no longer truncates silently;
|
of only the fixed widths, so a 32-bit `uint` no longer truncates silently;
|
||||||
decoding a finite float beyond the `float32` range is an overflow error
|
decoding a finite float beyond the `float32` range is an overflow error
|
||||||
|
|||||||
@@ -331,6 +331,11 @@ tree, _ := interpres.Parse([]byte(`arr = [1, {a = 2}, "x"]`))
|
|||||||
out, _ := interpres.Marshal(tree) // arr = [1, {a = 2}, "x"]
|
out, _ := interpres.Marshal(tree) // arr = [1, {a = 2}, "x"]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
A `[]any` holding only tables keeps the value-array form as well, because that
|
||||||
|
is the shape `Parse` gives a value array of inline tables; emitting it as
|
||||||
|
`[[headers]]` would re-parse as `[]map[string]any` and change the value's type
|
||||||
|
across a round-trip.
|
||||||
|
|
||||||
### Empty arrays
|
### Empty arrays
|
||||||
|
|
||||||
A nil slice is always omitted. An empty (length 0) array of tables is always
|
A nil slice is always omitted. An empty (length 0) array of tables is always
|
||||||
|
|||||||
@@ -388,6 +388,13 @@ func addArrayValue(doc *tomlDoc, name string, v reflect.Value, ctx string) error
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// A []any of tables is what Parse produces for a value array of inline
|
||||||
|
// tables; the [[header]] form would re-parse as []map[string]any and so
|
||||||
|
// change the value's Go type across a round-trip. The header form is
|
||||||
|
// reserved for typed table slices.
|
||||||
|
if v.Type().Elem().Kind() == reflect.Interface {
|
||||||
|
allTables = false
|
||||||
|
}
|
||||||
if allTables {
|
if allTables {
|
||||||
subs := make([]*tomlDoc, n)
|
subs := make([]*tomlDoc, n)
|
||||||
for i := range n {
|
for i := range n {
|
||||||
|
|||||||
@@ -597,6 +597,36 @@ func TestMarshalMixedArrayWithInlineTable(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A []any of tables is what Parse produces for a value array of inline
|
||||||
|
// tables; it must stay in the value-array form, or the output would re-parse
|
||||||
|
// as []map[string]any and the round-trip would change the value's type.
|
||||||
|
func TestMarshalValueArrayOfTablesStaysInline(t *testing.T) {
|
||||||
|
for _, doc := range []string{
|
||||||
|
"0=[{}]",
|
||||||
|
"a = [{x = 1}, {x = 2}]\n",
|
||||||
|
"b = [{x = 1}, 2, \"three\"]\n",
|
||||||
|
} {
|
||||||
|
tree, err := Parse([]byte(doc))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("%s: parse: %v", doc, err)
|
||||||
|
}
|
||||||
|
out, err := Marshal(tree)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("%s: marshal: %v", doc, err)
|
||||||
|
}
|
||||||
|
if bytes.HasPrefix(out, []byte("[[")) {
|
||||||
|
t.Errorf("%s: emitted the [[header]] form for a value array:\n%s", doc, out)
|
||||||
|
}
|
||||||
|
re, err := Parse(out)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("%s: re-parse: %v\ndoc:\n%s", doc, err, out)
|
||||||
|
}
|
||||||
|
if !tomlEqual(tree, re) {
|
||||||
|
t.Errorf("%s: round-trip changed the tree:\nwas: %#v\nnow: %#v\ndoc:\n%s", doc, tree, re, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestMarshalNestedInlineTables(t *testing.T) {
|
func TestMarshalNestedInlineTables(t *testing.T) {
|
||||||
tree := map[string]any{
|
tree := map[string]any{
|
||||||
"mix": []any{
|
"mix": []any{
|
||||||
|
|||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
go test fuzz v1
|
||||||
|
[]byte("0=[{}]")
|
||||||
Reference in New Issue
Block a user