Targets the TOON v4.1 specification. Nested objects stay in tables through nested field groups, and objects of uniform objects get a keyed table form. Encoder and decoder are rewritten against the spec and pass all 538 official fixtures.
Upgrading from 1.x
- If you only encode for an LLM, update a published config (Migration step 1) and you're done.
- If you decode this package's output elsewhere, or store it, upgrade those decoders first and re-encode stored TOON (steps 4 and 5).
- If you construct
ToonEncoderorToonDecoderyourself, or callArrayFlattenerorArrayUnflattener, see steps 2 and 3.
Breaking
- Nested objects in tabular arrays encode as nested field groups (
{id,artist{id,name}}) instead of dot-notation columns ({id,artist.id,artist.name}). The decoder reads dotted field names as literal keys. - Arrays whose nested objects differ in shape use list form instead of a padded table with
nullcells. - Objects whose values are two or more uniform objects encode in keyed tabular form (
servers[2:]{host,port}:). - Empty arrays encode as
key: []and root[]instead ofkey[0]:. - Strings starting with
#or containing[,]anywhere are quoted. - Empty tabular cells decode to
""instead ofnull. - The decoder drops legacy backslash unescaping (
Hello\, World). Unquoted tokens decode as-is. - Invalid escape sequences, unterminated strings and bare scalar lines error in non-strict mode too.
- Requires Laravel 12 or 13. Every Laravel 10 and 11 release carries unpatched security advisories, and Composer refuses to install them by default. Stay on 1.x for those versions.
number_precisionrounds to canonical form:99.5, not99.50, and100, not100.00.min_rows_for_tabledefaults to1. The spec requires tabular form for every uniform array.ToonEncoderandToonDecodertake the config array as their only constructor argument.toon_decode()returnsmixed, so a root primitive comes back as itself.- Removed the
key_folding,key_folding_depthandexpand_pathsconfig options, following their removal from the spec. - Removed the
max_flatten_depthconfig option. Nested field groups have no depth limit. - Removed the
ArrayFlattenerandArrayUnflattenersupport classes.
Added
- Keyed tabular form for objects of uniform objects, encode and decode.
- Nested field groups at any depth, encode and decode.
- Full-line
#comments are skipped when decoding. \uXXXXescapes for control characters.- Strict-mode errors for malformed headers, duplicate keys, indentation jumps and trailing content after a root array.
BackedEnum,JsonSerializableandStringablevalues are normalized before encoding.
Fixed
- Keys containing
.inside nested objects no longer break tabular encoding (#13). truncate_stringscounts characters, so a cut never splits a multibyte character.
Migration
- Remove
max_flatten_depth,key_folding,key_folding_depthandexpand_pathsfrom a publishedconfig/toon.php, and setmin_rows_for_tableto1. - Pass the config as the first constructor argument:
new ToonEncoder($config). A 1.x call,new ToonEncoder(null, $config), still runs on 2.0 and ignores$config. ArrayFlattenerandArrayUnflattenerhave no replacement. The encoder and decoder handle nesting themselves.- Re-encode stored TOON that used dot-notation columns, key folding or 0.x backslash escaping: decode it with 1.x, encode it with 2.0.
- Update decoders that read this package's output before upgrading the encoder. A 1.x decoder misreads nested field groups, keyed tables and empty arrays without an error:
tags: []comes back as the string"[]".