Module
LinkParse TOML 1.0 documents into TOMLValue, write deterministic TOML, and convert JSON through explicit Result values. Date kinds and numeric precision follow the format conversion rules.
Why
LinkConfiguration data keeps TOML parsing separate from conversions that may lose representable information.
Availability
LinkImport std.toml in language mode 5.21. The current compiler selects std/toml.tpz for this language mode. Availability in other released editions and inclusion in each installed distribution are Pending.
Exported types
Linkexport type TOML
Type members keep the compiler-owned type name shown in their declarations. Importing a module does not create a new type identity.
Public API
LinkPending contracts
LinkParse complete TOML 1.0 documents
LinkParse complete TOML 1.0 documents
parse accepts a complete TOML 1.0 document. An empty document or comments with whitespace produce an empty root table. Basic and literal strings, multiline strings, dotted and quoted keys, inline tables, arrays and arrays of tables retain their TOML meanings.
Integers must fit the signed 64 bit range. TOML decimal, hexadecimal, octal and binary spellings and valid underscore separators are accepted. Floating values use IEEE binary64 rounding. The TOML inf and nan forms are valid TOML values. Finite overflow follows the TOML numeric error boundary and returns Err.
Offset date times, local date times, local dates and local times remain distinct TOML kinds. Invalid calendar fields and time fields return Err. Strings that resemble dates remain strings.
A key or table definition may not redefine an existing value under the TOML 1.0 rules. Names are compared after decoding. Malformed escapes, leading zeroes and misplaced underscore separators return Err without exposing a partial document.
A failure returns a nonempty string identifying the cause, one based line and Unicode scalar column. CRLF is a single line break. The first offending scalar is the location and an incomplete input points immediately after its last scalar. Source comments and layout are not retained in TOMLValue.
The text argument is evaluated once. Parsing consumes the complete document, performs no I/O and does not invoke JSON conversion. Syntax failures use Err rather than a runtime diagnostic.
Why
Configuration files need a named format version and predictable rejection of invalid definitions. Preserving TOML kinds lets callers choose a separate and explicit conversion into JSON.
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 919 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1031 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1123 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1276 - compiler/crates/topaz_self_frontend/topaz/emitter/builtins.tpz at
912a5e86e1f9· 136 - toml.md at
1.0.0· 1 -
topaz.stdlib.contract.toml-parseatworking-tree - topaz.decision.toml-one-and-conversion.1 at
topaz.decisi
Parse a table and write its deterministic form
Linkimport std.tomlimport std.testimport std.iolet value = test.assertOk(toml.parse("title = \"Topaz\"\ncount = 6\nactive = true\n[page]\nwidth = 210\n"))io.writeLine(test.assertOk(toml.stringify(value)))let empty = test.assertOk(toml.parse(" # comment\n"))test.assertEq(test.assertOk(toml.stringify(empty)), "")
active = true count = 6 title = "Topaz" [page] width = 210
Expected result
Expected result
Execution completes. Exit code 0.
active = truecount = 6title = "Topaz"[page]width = 210
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 919 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1031 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1123 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1276 - compiler/crates/topaz_self_frontend/topaz/emitter/builtins.tpz at
912a5e86e1f9· 136 - toml.md at
1.0.0· 1 -
topaz.stdlib.contract.toml-parseatworking-tree - topaz.decision.toml-one-and-conversion.1 at
topaz.decisi
Accept literal strings, multiline values, radix integers and dates
Linkimport std.tomlimport std.iofor text in (["title = 'ink#paper'\n", "text = \"\"\"\nfirst\nsecond\"\"\"\n", "value = 0xff\n", "date = 1979-05-27T07:32:00Z\n", "value = inf\n", "value = nan\n"]) {match (toml.parse(text)) {case Ok(_) => io.writeLine("accepted")case Err(_) => io.writeLine("rejected")}}
accepted accepted accepted accepted accepted accepted
Expected result
Expected result
Execution completes. Exit code 0.
acceptedacceptedacceptedacceptedacceptedaccepted
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 919 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1031 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1123 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1276 - compiler/crates/topaz_self_frontend/topaz/emitter/builtins.tpz at
912a5e86e1f9· 136 - toml.md at
1.0.0· 1 -
topaz.stdlib.contract.toml-parseatworking-tree - topaz.decision.toml-one-and-conversion.1 at
topaz.decisi
Reject malformed numeric spellings and repeated definitions
Linkimport std.tomlimport std.iofor text in (["n = 1__0\n", "n = 01\n", "[a]\nx = 1\n[a]\ny = 2\n", "x = 1\nx = 2\n"]) {match (toml.parse(text)) {case Ok(_) => io.writeLine("accepted")case Err(_) => io.writeLine("invalid")}}
invalid invalid invalid invalid
Expected result
Expected result
Execution completes. Exit code 0.
invalidinvalidinvalidinvalid
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 919 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1031 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1123 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1276 - compiler/crates/topaz_self_frontend/topaz/emitter/builtins.tpz at
912a5e86e1f9· 136 - toml.md at
1.0.0· 1 -
topaz.stdlib.contract.toml-parseatworking-tree - topaz.decision.toml-one-and-conversion.1 at
topaz.decisi
Return line and scalar column in a TOML error
Linkimport std.tomlimport std.testimport std.iolet error = test.assertErr(toml.parse("x = ?"))test.assertContains(error, "line 1")test.assertContains(error, "column 5")io.writeLine("located")
located
Expected result
Expected result
Execution completes. Exit code 0.
located
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 919 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1031 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1123 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1276 - compiler/crates/topaz_self_frontend/topaz/emitter/builtins.tpz at
912a5e86e1f9· 136 - toml.md at
1.0.0· 1 -
topaz.stdlib.contract.toml-parseatworking-tree - topaz.decision.toml-one-and-conversion.1 at
topaz.decisi
Write deterministic TOML documents
LinkWrite deterministic TOML documents
stringify accepts a TOMLValue whose root is a table. A scalar or array root returns Err because it is not a TOML document. An empty table becomes empty text.
Each table writes its scalar and array entries before child table sections. Both groups follow the decoded key order. Arrays retain element order. Table headers use the complete dotted path. A noninitial table section is separated by one blank line.
Assignments use one space on either side of the equals sign. Inline arrays and tables use a comma followed by one space. Every nonempty document uses LF line endings and ends with one LF. Comments, indentation and source ordering are not reproduced.
Bare keys use the TOML ASCII key alphabet. Other keys and string values use basic quoted strings with deterministic escaping. Integers use decimal digits without separators. Finite floats use the shortest binary64 roundtrip value and retain a decimal point or exponent to distinguish a float from an integer. Positive and negative zero are written as 0. and -. Nonfinite values use inf, - or nan.
Dates and times use their TOML kind, a capital T separator and a capital Z for a zero offset. Local kinds retain their lack of an offset. Fractional seconds omit redundant trailing zeroes.
The value argument is evaluated once. Serialization performs no I/O, does not mutate the value and returns Err without partial output when the value cannot form a document. Parse the result with toml. to recover the same TOML kinds and values.
Why
A deterministic writer supports stable configuration diffs. Requiring a table root makes its successful output usable as a complete TOML document, and numeric normalization follows the stored numeric value.
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1329 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1356 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1387 - compiler/crates/topaz_self_frontend/topaz/emitter/builtins.tpz at
912a5e86e1f9· 137 -
topaz.stdlib.contract.toml-stringifyatworking-tree - topaz.decision.toml-one-and-conversion.1 at
topaz.decisi
Reject a scalar as a complete TOML document
Linkimport std.jsonimport std.tomlimport std.testimport std.iolet tree = test.assertOk(json.parse("7"))let value = test.assertOk(toml.fromJson(tree))match (toml.stringify(value)) {case Ok(_) => io.writeLine("accepted")case Err(_) => io.writeLine("root table required")}
root table required
Expected result
Expected result
Execution completes. Exit code 0.
root table required
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1329 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1356 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1387 - compiler/crates/topaz_self_frontend/topaz/emitter/builtins.tpz at
912a5e86e1f9· 137 -
topaz.stdlib.contract.toml-stringifyatworking-tree - topaz.decision.toml-one-and-conversion.1 at
topaz.decisi
Write the binary64 value rather than its input spelling
Linkimport std.tomlimport std.testimport std.iolet value = test.assertOk(toml.parse("x = 0.10000000000000001\n"))io.writeLine(test.assertOk(toml.stringify(value)))
x = 0.1
Expected result
Expected result
Execution completes. Exit code 0.
x = 0.1
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1329 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1356 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1387 - compiler/crates/topaz_self_frontend/topaz/emitter/builtins.tpz at
912a5e86e1f9· 137 -
topaz.stdlib.contract.toml-stringifyatworking-tree - topaz.decision.toml-one-and-conversion.1 at
topaz.decisi
Convert TOML and JSON with explicit failures
LinkConvert TOML and JSON with explicit failures
from recursively converts a JSONValue into a TOMLValue and returns Result<TOML. Booleans, strings, arrays and objects retain their values and structure. JSON null has no TOML representation and returns Err, including a nested null.
An integer lexeme must fit signed 64 bit and becomes a TOML integer. An out of range integer returns Err rather than changing into a float. A fractional or exponent lexeme becomes binary64 with nearest ties to even rounding. Overflow to infinity returns Err. Finite rounding and underflow may change the exact decimal value.
A string is kept as a string even when it resembles a date or time. Converting a JSON scalar or array is permitted, but writing it as a complete TOML document still requires a root table.
TOML recursively converts a TOML value. Tables become objects and arrays retain order. Finite numbers follow JSON numeric conversion. Nonfinite numbers return Err rather than becoming a string or null.
TOML dates and times become strings in the normalized TOML spelling used by the writer. This conversion loses their TOML kind. JSON also does not distinguish an integer from an integral float. A reverse conversion therefore need not restore the original TOML kinds. Comments and source number spellings are not preserved.
Both conversions visit array elements by index and object or table keys in the decoded key order. They stop at the first unrepresentable child. The nonempty error identifies its path rooted at $ and its cause. Inputs remain unchanged and neither conversion performs I/O.
Why
A format conversion must expose values that its destination cannot represent. A Result keeps nonfinite failure explicit and avoids inventing a second conversion function or silently changing a numeric value into another kind.
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1428 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1456 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1534 - compiler/crates/topaz_self_frontend/topaz/emitter/builtins.tpz at
912a5e86e1f9· 138 -
topaz.stdlib.contract.toml-jsonatworking-tree - topaz.decision.toml-one-and-conversion.1 at
topaz.decisi
Reject null and out of range integer conversion
Linkimport std.jsonimport std.tomlimport std.testimport std.iofor text in (["null", "9223372036854775808", "1e9999"]) {let value = test.assertOk(json.parse(text))match (toml.fromJson(value)) {case Ok(_) => io.writeLine("accepted")case Err(_) => io.writeLine("unrepresentable")}}
unrepresentable unrepresentable unrepresentable
Expected result
Expected result
Execution completes. Exit code 0.
unrepresentableunrepresentableunrepresentable
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1428 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1456 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1534 - compiler/crates/topaz_self_frontend/topaz/emitter/builtins.tpz at
912a5e86e1f9· 138 -
topaz.stdlib.contract.toml-jsonatworking-tree - topaz.decision.toml-one-and-conversion.1 at
topaz.decisi
Identify the first unrepresentable child
Linkimport std.jsonimport std.tomlimport std.testimport std.iolet value = test.assertOk(json.parse("\{\"x\":[null]\}"))let error = test.assertErr(toml.fromJson(value))test.assertContains(error, "$.x[0]")io.writeLine("child located")
child located
Expected result
Expected result
Execution completes. Exit code 0.
child located
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1428 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1456 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1534 - compiler/crates/topaz_self_frontend/topaz/emitter/builtins.tpz at
912a5e86e1f9· 138 -
topaz.stdlib.contract.toml-jsonatworking-tree - topaz.decision.toml-one-and-conversion.1 at
topaz.decisi
Convert a TOML table through a recoverable JSON result
Linkimport std.jsonimport std.tomlimport std.testimport std.iolet value = test.assertOk(toml.parse("name = \"Topaz\"\ncount = 6\n"))let tree = test.assertOk(value.toJson())io.writeLine(test.assertOk(json.stringify(tree)))let restored = test.assertOk(toml.fromJson(tree))io.writeLine(test.assertOk(toml.stringify(restored)))
{"count":6,"name":"Topaz"}
count = 6
name = "Topaz"
Expected result
Expected result
Execution completes. Exit code 0.
{"count":6,"name":"Topaz"}count = 6name = "Topaz"
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1428 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1456 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1534 - compiler/crates/topaz_self_frontend/topaz/emitter/builtins.tpz at
912a5e86e1f9· 138 -
topaz.stdlib.contract.toml-jsonatworking-tree - topaz.decision.toml-one-and-conversion.1 at
topaz.decisi
Return an error for a TOML infinity during JSON conversion
Linkimport std.tomlimport std.testimport std.iolet value = test.assertOk(toml.parse("value = inf\n"))match (value.toJson()) {case Ok(_) => io.writeLine("accepted")case Err(_) => io.writeLine("nonfinite rejected")}
nonfinite rejected
Expected result
Expected result
Execution completes. Exit code 0.
nonfinite rejected
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1428 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1456 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 1534 - compiler/crates/topaz_self_frontend/topaz/emitter/builtins.tpz at
912a5e86e1f9· 138 -
topaz.stdlib.contract.toml-jsonatworking-tree - topaz.decision.toml-one-and-conversion.1 at
topaz.decisi