126 lines
6.1 KiB
Markdown
126 lines
6.1 KiB
Markdown
# Changelog
|
|
|
|
All notable changes to **interpres** are documented in this file.
|
|
|
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
|
## [development]
|
|
|
|
### Added
|
|
|
|
- TOML 1.1 support, on by default: date-times and times without seconds
|
|
(`07:32`, `1979-05-27T07:32`, normalised to full seconds on output), the
|
|
`\e` and `\xHH` escape sequences, and multi-line inline tables with
|
|
comments and trailing commas. The compliance suite runs in TOML 1.1 mode:
|
|
214 valid and 467 invalid cases, zero failures. Every TOML 1.0 document
|
|
parses exactly as before.
|
|
- `interpres-decode -validate [file ...]`: a validate mode beside the
|
|
toml-test adapter. It parses each named file, or stdin when none are named,
|
|
prints one line per invalid document to stderr, and exits 0 when all are
|
|
valid, 1 when one is not, and 2 on a usage or read failure. Install it with
|
|
`go install .../cmd/interpres-decode@latest`; releases still ship no
|
|
binaries.
|
|
- `DecodeError` and `EncodeError`: decode and encode failures are wrapped in
|
|
typed errors carrying the key path, read with `errors.AsType` instead of
|
|
parsing the message text. The rendered messages keep their shape; the only
|
|
visible change is that an encode failure on a top-level field no longer
|
|
gains a meaningless leading dot in its path.
|
|
- `omitzero` and `omitempty` tag options on encode: `toml:"name,omitzero"`
|
|
skips a field whose value is the zero value of its type (a type with an
|
|
`IsZero() bool` method decides through the method), and
|
|
`toml:"name,omitempty"` skips a nil or empty slice, array, or map. The
|
|
decoder ignores both options.
|
|
|
|
### Changed
|
|
|
|
- The compliance suite is [toml-test](https://github.com/toml-lang/toml-test)
|
|
v2.2.0, run in TOML 1.0 mode. The new corpus holds 205 valid and 474 invalid
|
|
cases (v1.6.0 had 185 and 371), and it caught the two documents the parser
|
|
still accepted, fixed below.
|
|
|
|
### Fixed
|
|
|
|
- A float with an exponent marker but no digits (`1e`, `0.0E`) is rejected;
|
|
the exponent requires at least one digit.
|
|
- A date-time offset outside 00:00 through 23:59 is rejected; such offsets
|
|
were accepted and silently rolled over (`+00:60` decoded as `+01:00`).
|
|
- Untagged embedded fields now decode symmetrically with encode: an embedded
|
|
struct receives its keys inline (a nil embedded pointer struct is
|
|
allocated), an embedded map catches the keys no field claims, and a name
|
|
clash resolves in favour of the shallower field. A struct with an untagged
|
|
embedded field previously decoded with all inline keys dropped and did not
|
|
round-trip.
|
|
- `Marshal` re-emits arrays that mix tables with scalars: the table elements
|
|
render as inline tables inside the value array. A tree that `Parse` accepts
|
|
from such a document previously failed with
|
|
`cannot encode map[string]interface {}`.
|
|
|
|
## [1.0.0] - 2026-08-20
|
|
|
|
First stable release: a dependency-free TOML 1.0 parser and encoder for Go that
|
|
uses only the standard library and passes the entire
|
|
[toml-test](https://github.com/toml-lang/toml-test) suite
|
|
(**185 valid and 371 invalid cases, 0 failures**).
|
|
|
|
### Added
|
|
|
|
**Parsing**
|
|
|
|
- `Parse(data []byte) (map[string]any, error)`: decode a TOML document into an
|
|
untyped tree.
|
|
- Full TOML 1.0 syntax: comments; bare, quoted, and dotted keys; tables
|
|
(`[a.b]`) and arrays of tables (`[[a]]`); basic and literal strings, including
|
|
multiline (`"""` / `'''`) with escape sequences and line-ending backslash
|
|
trimming; integers in decimal, hex (`0x`), octal (`0o`), and binary (`0b`)
|
|
with `_` separators; floats with exponents and `inf` / `nan`; booleans;
|
|
offset/local date-times, dates, and times; arrays; and inline tables.
|
|
- Distinct date-time types: offset date-times decode to `time.Time`, while
|
|
`LocalDateTime`, `LocalDate`, and `LocalTime` represent the local variants,
|
|
each with a `String()` method returning the TOML-canonical rendering.
|
|
- Strict, spec-conformant validation that rejects invalid documents: leading
|
|
zeros, misplaced underscores, malformed floats and radix literals, control
|
|
characters in strings and comments, bare carriage returns, non-UTF-8 input,
|
|
out-of-range Unicode escapes, multiline strings used as keys, single-digit
|
|
date-time components, duplicate/overwriting inline-table keys, and the full
|
|
family of table redefinitions (header vs. header, header vs. dotted key,
|
|
array of tables vs. table, and dotted-key appends to defined tables).
|
|
- `SyntaxError` carrying the 1-based line of a malformed document.
|
|
|
|
**Decoding**
|
|
|
|
- `Unmarshal(data []byte, v any)`: parse and map onto a struct or
|
|
`map[string]any` via reflection, with overflow-checked numeric conversion,
|
|
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
|
|
without a destination field, at every struct depth.
|
|
- `Unmarshaler` interface (`UnmarshalTOML(data any) error`) for types that take
|
|
full control of their decode.
|
|
|
|
**Encoding**
|
|
|
|
- `Marshal(v any) ([]byte, error)`: encode a struct or `map[string]V` value to
|
|
a TOML 1.0 document that re-parses to an equivalent value tree.
|
|
- `Encoder` with chainable policy options: `GroupByKind` (group-by-kind layout
|
|
versus declaration order), `OmitEmptyArrays`, and `UseLiteralMultiline`.
|
|
- `Marshaler` interface (`MarshalTOML() (any, error)`) for types that need a
|
|
custom TOML shape; the returned value is encoded normally.
|
|
|
|
**Cancellation**
|
|
|
|
- `ParseContext`, `UnmarshalContext`, `MarshalContext`,
|
|
`(*Decoder).DecodeContext` and `(*Encoder).MarshalContext` honour a
|
|
`context.Context`, checked up front and every 64 statements or fields.
|
|
|
|
**Project**
|
|
|
|
- Standard library only: zero third-party modules.
|
|
- `cmd/interpres-decode`, a toml-test harness adapter (TOML on stdin, tagged
|
|
JSON on stdout).
|
|
- A runnable example, a table-driven Go test suite, and a canonical `just`
|
|
recipe set whose `gates` recipe is the definition of done.
|
|
- Hand-written CI pipelines for the test, race and release gates.
|
|
- `SECURITY.md` for private vulnerability reports.
|