v3.2.0
Changes in v3.2.0
This release brings the library into conformance with TOON Specification v3.3 (upstream advanced v3.0 → v3.3) and adds a validation API.
Added
- TOON Specification v3.3 compliance. See
docs/SPEC.mdanddocs/CHANGELOG.md. - Unicode escapes (§7.1): the encoder emits C0 control characters (U+0000–U+001F except
\n,\r,\t) as\uXXXX; the decoder accepts\uXXXX(case-insensitive hex) and rejects lone surrogates and escapes with fewer than four hex digits. - Empty-array decoding (§9.1): the decoder now accepts the canonical
[]andkey: []forms in addition to the legacy[0]:/key[0]:forms. - Validation API:
Toon::validate(),toon_validate()andtoon_validate_lenient()for checking TOON syntax without decoding. - Spec conformance tests in
tests/Spec/Version31To33ComplianceTest.php.
Changed
- Number formatting (§2): finite numbers use canonical decimal only for
n = 0or1e-6 ≤ |n| < 1e21; values outside that range use exponent notation (lowercasee, explicit sign, e.g.1e+21,1e-7). Large in-domain floats are no longer quoted as strings, and very small numbers no longer underflow to0. - Control characters are no longer rejected on encode — they are escaped and preserved as data (§15).
- Strict decoding now rejects leading-zero / malformed bracket lengths such as
[03](§6, §14.2), header delimiter mismatches where the bracket delimiter differs from the field-list delimiter, e.g.rows[2|]{a,b}:(§6, §14.2), and duplicate sibling keys at the same depth (§8, §14.4). Non-strict mode treats malformed bracket tokens as literal keys and applies last-write-wins for duplicate keys.
Fixed
- Decoder: quoted object keys containing colons (e.g.
"App\Controller::method") now decode correctly (#4, #5). - Decoder:
key: []previously decoded tonulland a bare[]crashed with an uninitialized-offset warning; both now decode to an empty array. - Decoder — single-line list items (§9.2/§9.4/§10): a list item whose entire content is on the hyphen line now decodes by shape instead of as a plain string —
- [M]: …→ inner array,- key: …→ object, bare-→ empty object. This fixes round-trips for arrays of arrays and lists of single-field objects. - Decoder — empty document (§5): an empty or whitespace-only document decodes to an empty object in both modes, instead of throwing (strict) or returning
null(lenient). - Decoder — bare
key:(§8): decodes to an empty object, notnull. - Decoder — quoted header keys (§7.4): a quoted key prefix such as
"my-key"[3]:is unescaped. - Decoder — empty inline/tabular tokens (§9.1/§11.2): decode to the empty string instead of throwing (e.g.
[3]: a,,b→['a','','b']). - Decoder — backslash handling (§7.1/§11.2): an unquoted backslash is a literal character (escapes apply only inside quoted strings), and colon detection tracks quote state so a key ending in an escaped backslash (
"a\\": c) parses. - Options (§12):
EncodeOptions/DecodeOptionsrejectindent < 1;EncodeOptions::compact()now usesindent: 1so nested output round-trips. - Validation:
Toon::validate()now runs the full decoder internally and returnsfalseonly whendecode()throws, so validation and decoding can never disagree. The separate validator implementation was removed.
Full Changelog: v3.1.0...v3.2.0