toml.parse used to read a subset:
[sections], and string, integer and boolean values. An
array, a float, an inline table or a date came back as an error, so a
config file using any of them could not be read at all. That subset is
gone. toml.parse now reads TOML 1.0, and
toml.encode writes it.
import toml
match toml.parse(text)
Ok(cfg) -> print((cfg @ "worker")[1] @ "name")
Error(why) -> print(why)
end
An array is an array you can index and iterate.
[[worker]] is an array of tables, in file order. A date is
a datetime you can do arithmetic on rather than a string
you have to parse again. Integers take the 0x,
0o and 0b bases and 1_000
underscores, floats take inf and nan, and
strings come in all four TOML spellings with escapes processed where the
spec says they should be.
Replacing the parser instead of extending it was forced. It worked a
line at a time, and arrays and inline tables span lines, so those were
out of reach from that shape at any amount of effort. What settled it is
that the old parser did not only refuse what it could not read. Three
inputs parsed to the wrong value and reported nothing:
x = """hi""" came back as the string ""hi"",
x = "say \"hi\"" kept its backslashes instead of unescaping
them, and a [[section]] header became an ordinary table
whose name was literally [section]. If you built a
workaround for one of those, you can drop it.
Two more silent wrong answers went with it. A date that does not
exist used to become a nearby real one, so 1979-99-99 read
as 1987-06-07 and 2026-01-32 as the first of February. Both
are refused now, leap years counted properly. A document that fails to
parse also says which line it failed on rather than only that it
failed.
toml.encode sorts its keys, so the same table produces
the same text every run and a config file does not reshuffle itself in
version control. Exact decimal and money
values are written as strings, because TOML's only number types are
64-bit integer and float and either would drop the exactness those types
exist to hold. A value with no TOML form at all, like
bytes, raises a fault instead of being approximated into
one.
Before you round-trip a file, two limits. A bare local time,
07:32:00 with no date, reads as a string, because SCUA has
no time-of-day type and inventing a date for it would be worse than
saying so. And a date's spelling does not survive a read-modify-write: a
datetime is an instant plus an offset and carries no record
of having been written date-only, so 2026-08-19 read in and
written back out comes out as 2026-08-19T00:00:00Z. Same
instant, longer spelling. Where the exact shape of a file matters, edit
the text.