feat!: rework the public API to json/v2-style variadic options
Test / test (push) Successful in 1m49s
Test / test (push) Successful in 1m49s
Assisted-by: GLM 5.3 Flash
This commit is contained in:
+24
-18
@@ -24,7 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
toml-test tagged JSON from stdin and writes the TOML document it describes.
|
||||
The compliance suite now runs the encoder as well as the decoder, 214
|
||||
encoder cases against the tagged JSON of the valid corpus.
|
||||
- `Encoder.InlineTables(threshold)`: a sub-table whose single-line rendering is
|
||||
- `InlineTables(threshold)`: a sub-table whose single-line rendering is
|
||||
at most `threshold` bytes is written as an inline table instead of a header
|
||||
section, which shortens a document of small tables. An array of tables keeps
|
||||
its header form, because its inline form would re-parse as a value array.
|
||||
@@ -47,7 +47,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
the plain type takes an offset date-time as it always did; code that asserts
|
||||
the tree's type, and `UnmarshalTOML` implementations that expect a
|
||||
`time.Time`, need the new type.
|
||||
- `Decoder.MaxDepth(depth)` and `Decoder.MaxInputSize(size)` bound the parse a
|
||||
- `MaxNestingDepth(depth)` and `MaxInputSize(size)` options bound the parse a
|
||||
`Decode` performs, and every parse carries a nesting limit in any case
|
||||
(10000 levels, which no hand-written document approaches): a document that
|
||||
nests arrays or inline tables deeper used to run the stack out and is now
|
||||
@@ -60,12 +60,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- `ParseAs[T](data)`, the generic one-line decode, and `NewSchema[T]()`,
|
||||
which precompiles the struct schema and the interface flags for a hot path
|
||||
before the first document arrives.
|
||||
- `Encoder.EmitFieldComments()` prints the comment a field's `toml` tag
|
||||
- `EmitFieldComments(true)` prints the comment a field's `toml` tag
|
||||
carries in a `comment=` option above the field's line or header, the
|
||||
comments a round trip through the Go type would otherwise drop. Go doc
|
||||
comments are not visible to reflection, so the tag is the channel that
|
||||
carries the text.
|
||||
- `Decoder.LocalTimeLocation(loc)` lets a local date-time fill a plain
|
||||
- `LocalTimeLocation(loc)` lets a local date-time fill a plain
|
||||
`time.Time` destination in the location given, relabelled rather than
|
||||
shifted: `07:32` in the document is `07:32` in the zone. Without the
|
||||
option the wrapper types remain the only destinations a local kind fills.
|
||||
@@ -78,9 +78,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
order on decode and sorts on encode. It works as a decode target on its
|
||||
own, in a struct field, and as the element of an array of tables; its
|
||||
values are untyped, so a nested table stays a `map[string]any`.
|
||||
- `UnmarshalWithOptions(data, v, opts)` decodes with a `DecodeOptions` struct
|
||||
in one call, the options a `Decoder` sets without building one: unknown
|
||||
keys, `Number` literals, and the parse limits.
|
||||
- `Unmarshal(data, v, opts...)` and the other entries take variadic options,
|
||||
the shape encoding/json/v2 uses: `RejectUnknownFields`,
|
||||
`NumbersAsLiterals`, `MaxNestingDepth`, `MaxInputSize`,
|
||||
`LocalTimeLocation`. `MarshalWrite(w, v, opts...)` and
|
||||
`UnmarshalRead(r, v, opts...)` are the streaming forms.
|
||||
- `Marshal` carries a nesting limit of 10000 levels, the parser's own figure:
|
||||
cyclic data, which used to run the stack out, is now rejected with an error
|
||||
that names the limit and the path it was met at.
|
||||
@@ -126,7 +128,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
the input. An input that is not valid UTF-8 names the offset of the first
|
||||
invalid byte in its message. The new fields are additive: a `SyntaxError`
|
||||
built from a line and a message alone is unchanged.
|
||||
- `Decoder.UseNumber()` decodes the integers and floats of the document into
|
||||
- `NumbersAsLiterals(true)` decodes the integers and floats of the document into
|
||||
`Number`, which carries the literal the document wrote, so `0x1f`, `1_000`,
|
||||
`+1.0` and `inf` survive a round trip with their spelling instead of the
|
||||
normalised `31`, `1000` and `1.0`. Typed destinations take the evaluated
|
||||
@@ -136,11 +138,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Changed
|
||||
|
||||
- `Encoder.GroupByKind(bool)` is renamed to `Encoder.Layout(kind)` and takes
|
||||
a `LayoutKind`: `LayoutKindGrouped`, the default, or
|
||||
`LayoutKindDeclaration` for the declaration order. `UseLiteralMultiline`
|
||||
is renamed to `LiteralMultiline`. The behaviour is unchanged; 2.0 is the
|
||||
only chance a rename has, and the migrator updates the calls mechanically.
|
||||
- The stateful `Decoder` and `Encoder` of 1.x are replaced by variadic
|
||||
options on the entries, the shape encoding/json/v2 uses: `Layout(kind)`
|
||||
with `LayoutKindGrouped` or `LayoutKindDeclaration`, `OmitEmptyArrays`,
|
||||
`LiteralMultiline(threshold)`, `InlineTables(threshold)`,
|
||||
`EmitFieldComments`, `RejectUnknownFields`, `NumbersAsLiterals`,
|
||||
`MaxNestingDepth`, `MaxInputSize`, `LocalTimeLocation`.
|
||||
- `DecodeError` and `EncodeError` carry one `Path` type, a list of segments
|
||||
(`"items"`, `"[0]"`, `"weight"`) with a `String()` rendering the TOML
|
||||
notation, `items[0].weight`. The decode error used to hold a bare
|
||||
@@ -275,9 +278,12 @@ destination field of type `time.Time` keeps working.
|
||||
`ParseMap` gives the plain `map[string]any` tree the old `Parse` returned.
|
||||
The document is writable, and `Marshal` writes it back with its comments.
|
||||
|
||||
**Renamed API.** `Encoder.GroupByKind(bool)` is `Encoder.Layout(kind)` with
|
||||
`LayoutKindGrouped` (the old default) and `LayoutKindDeclaration` (the old
|
||||
`false`); `UseLiteralMultiline` is `LiteralMultiline`.
|
||||
**Options instead of Decoder and Encoder.** The stateful types of 1.x are
|
||||
gone; the entries take variadic options, the shape encoding/json/v2 uses.
|
||||
`NewDecoder().DisallowUnknownFields().Decode(data, &cfg)` becomes
|
||||
`Unmarshal(data, &cfg, RejectUnknownFields(true))`, and the encoder
|
||||
methods become options: `Layout(LayoutKindDeclaration)` replaces
|
||||
`GroupByKind(false)`, `LiteralMultiline` replaces `UseLiteralMultiline`.
|
||||
|
||||
**Tag options.** `omitempty` follows encoding/json: it now also drops empty
|
||||
strings, zero numbers, `false`, nil pointers and nil interfaces. `required`
|
||||
@@ -293,7 +299,7 @@ match on the old messages would not see.
|
||||
|
||||
**Decoding shapes.** `map[string]any` values merge into a non-empty map
|
||||
destination; untagged embedded maps beyond the first stay empty; numbers can
|
||||
stay literals under `UseNumber`; local date-times can decode into
|
||||
stay literals under `NumbersAsLiterals`; local date-times can decode into
|
||||
`time.Time` under `LocalTimeLocation`. All three are opt-in or additive
|
||||
except where noted above.
|
||||
|
||||
@@ -442,7 +448,7 @@ uses only the standard library and passes the entire
|
||||
nested structs, slices, and `map[string]T`.
|
||||
- `toml:"name"` field tags, case-insensitive name fallback, and `toml:"-"` to
|
||||
skip a field.
|
||||
- `Decoder` with `DisallowUnknownFields` for strict decoding that rejects keys
|
||||
- `RejectUnknownFields(true)` option for strict decoding that rejects keys
|
||||
without a destination field, at every struct depth.
|
||||
- `Unmarshaler` interface (`UnmarshalTOML(data any) error`) for types that take
|
||||
full control of their decode.
|
||||
|
||||
Reference in New Issue
Block a user