toonlite now implements the TOON specification v4.4.0 and passes all 564 official conformance fixtures (404 decode, 160 encode), which run in the test suite. No fixture is skipped.
to_toon() and json_to_toon() return class "toonlite_toon" instead of
"toon", which clashed with the toon package's print method.Output is now canonical TOON, so most documents are written differently:
1,Ada,true, not 1, "Ada", true.1
(not 1.0), 0.1, 1e-7, 1e+21.tags[2]: a,b). A length-1 vector is a
primitive; wrap it in I() to write a one-element array.{id,geo{lat,lon}}) for nested records or data frame columns, and
objects of two or more uniform records as keyed tables (key[N:]{...}:).key: [] ([] at the root), empty objects key:.NA, NaN and Inf are always written as null.to_toon(), write_toon(),
write_toon_df() and toon_stream_write_rows() produce the same bytes for
the same data.format_toon() decodes and re-encodes, giving the canonical form.Input follows the spec, and strict = TRUE (the default) means the spec's
strict mode:
# comments are comments. // lines and trailing
# ... or // ... are content now, which usually makes them errors.strict = FALSE the last one wins silently, keeping the first position.strict = FALSE they are accepted with a warning
(the first five per document), in read_toon() as in read_toon_df().strict = FALSE
applies the spec's five recoveries instead.items[2]:); - lines under a plain
key: are no longer an array, and key: [3]: is not a header.05, .5, 1.
and +1 are strings). Integers outside R's integer range are doubles, and
numbers beyond the double range are -Inf/Inf.key: with nothing under it, or an empty document) is a
named list of length 0.key[N:]{fields}:), nested field groups, root forms and
every other v4.4 construct are read and written.indent (the spec's indentSize) for every reader and writer, and
delimiter (",", "\t" or "|") for every writer.toon_stream_items() now streams: items are decoded and handed to the
callback one batch at a time, with memory reused between batches, instead
of reading the whole file first. Tabular rows arrive as row objects.read_toon_df() and toon_stream_rows() read nested field groups into
columns named by their dotted path (geo.lat) and accept key: [].toon_info() gains strict and indent.Deprecated arguments are ignored and warn; the 0.1.1 deprecations still warn.
allow_comments in every reader and validator, and in toon_peek() and
toon_info(): comment lines are always skipped. Warns unless TRUE.allow_duplicate_keys in from_toon(), read_toon(), validate_toon(),
assert_toon() and toon_stream_items(): duplicates are governed by
strict. Warns when supplied.pretty in to_toon(), write_toon(), write_toon_df() and
json_to_toon(): pretty = FALSE produced invalid TOON. Warns unless
TRUE.strict in the writers (to_toon(), write_toon(), write_toon_df(),
json_to_toon() and the CSV, Parquet and Feather converters): NaN and
Inf are always null. Warns when supplied.allow_comments in to_toon(): encoders never write comments. Warns when
TRUE.read_toon_df() and toon_stream_rows() read a column mixing booleans
and numbers (true, 1.5) as character ("true", "1.5") with a
warning, instead of silently turning the booleans into 1 and 0.
read_toon() keeps such arrays as lists, as before.warn in toon_stream_items() did nothing. It now controls the
non-strict count mismatch warnings, as in toon_stream_rows(); they are
given after the last batch.validate_toon() attached its error attribute to R's shared FALSE
value, so unrelated FALSE results could carry it for the rest of the
session.read_toon_df() no longer rounds numbers to 6 decimals when a column falls
back to character; it keeps their canonical text.read_toon() stores values in a few flat arrays instead of one heap object
per value, and tabular arrays keep their cells in one block.snprintf() and
strtod() elsewhere.These follow from R's data model; see the README.
\u0000 (and NUL bytes) cannot be represented in R strings and are an
error when decoding.std::from_chars() for double. Doubles are now parsed with
std::from_chars() only when the standard library advertises it
(__cpp_lib_to_chars) and with strtod() otherwise, so libc++ builds on
Linux keep working too.toon_stream_write_rows() formats cells exactly like write_toon_df():
control characters are escaped, factors are written as their labels instead
of integer codes, and Inf/NaN are written as null instead of the
invalid token inf. Streamed files now read back identically to
write_toon_df() output.read_toon_df() and toon_stream_rows() decode quoted strings with the
same rules as read_toon(), including \uXXXX escapes and strict-mode
handling of invalid escapes.read_toon_df() and toon_stream_rows() no longer turn -2147483648 into
NA; like read_toon(), they read it as a double.to_toon() and write_toon_df() no longer fail in strict mode when a
double vector or column contains NA; it is written as null. Strict mode
still rejects NaN and Inf.json_to_toon() no longer warns that allow_comments has no effect.toon_stream_rows() now honours strict like read_toon_df() (tabs in
indentation are an error by default) and applies col_types to every
batch, not just the first.tabular in write_toon_df(), csv_to_toon(), parquet_to_toon() and
feather_to_toon() never changed the output. It is deprecated and warns
when set to anything other than TRUE.batch_size in toon_stream_write_rows() was never passed to
row_source. It is deprecated and warns when supplied.allow_duplicate_keys in read_toon_df() and toon_stream_rows() was
never used. It is deprecated and warns when set to anything other than
TRUE.