TOML
(require toml) | package: toml-lib |
This library provides utilities for parsing the TOML configuration file format to Racket values. See the TOML web site for more information about TOML.
Active development is ongoing. Please see the GitHub repository for more information.
1 TOML-expressions
A tomlexpr is a hash table with symbol? keys and values being one of:
procedure
(tomlexpr? x) → boolean?
x : any/c
> (tomlexpr? '#hasheq((n . 0))) #t
> (tomlexpr? '#hash((x . +inf.0))) #t
> (tomlexpr? 5) #f
> (tomlexpr? '#hash(("oops" . "keys must be symbols"))) #f
> (require gregor/time) > (tomlexpr? `#hasheq((xs . (1 "b" #hash((noon . ,(time 12))))))) #t
2 Parsing TOML Text
procedure
str : string?
Dates are returned using gregor structs.
> (parse-toml (string-append "[a.b]\n" "c = 1\n" "[a]\n" "d = 2")) '#hasheq((a . #hasheq((b . #hasheq((c . 1))) (d . 2))))
> (parse-toml "today = 2014-06-26T12:34:56Z") '#hasheq((today . #<moment 2014-06-26T12:34:56Z>))
> (parse-toml (string-append "[a]\n" "b = 1\n" "[a]\n" "c = 2")) toml: redefinition of `a'
> (parse-toml (string-append "x = 1\n" "x = 2\n")) toml: conflicting values for `x'
at 1:4: `1'
at 2:4: `2'
> (parse-toml (string-append "[fruit]\n" "apple.color = \"red\"\n" "apple.taste.sweet = true\n" "\n" "[fruit.apple]")) toml: redefinition of `fruit.apple' with dotted key
3 Generating TOML Text from TOML-expressions
procedure
(tomlexpr->string x) → string?
x : tomlexpr?
This function should be considered unstable. The output of (tomlexpr->string x) will continue to be a valid TOML string, but the exact formatting properties of the string should not be relied upon to remain fixed. Future versions may also add more arguments to control various aspects of this function.
The current properties of the string include:
Newlines are always LF, never CRLF.
Keys will be ordered according to string<? applied to the symbol->string of the keys.
Dotted keys are never used for terminal key/value pairs, though they may be used for table headers.
Inline table syntax is used only when necessary in lists.
Lists will be spread across multiple lines with a trailing comma for the final element.
> (tomlexpr->string '#hasheq((another-table . #hasheq((key . 10))) (table . #hasheq((key . 5) (array . (#hasheq((a . 1) (b . 2)) #hasheq((a . 2) (b . 4)))))))) "[another-table]\nkey = 10\n\n[table]\nkey = 5\n\n[[table.array]]\na = 1\nb = 2\n\n[[table.array]]\na = 2\nb = 4"
> (tomlexpr->string '#hasheq((list . (1 2 3)))) "list = [\n 1,\n 2,\n 3,\n]"
> (tomlexpr->string '#hasheq( (contributors . ("Foo Bar <foo@example.com>" #hasheq((name . "Baz Qux") (email . "bazqux@example.com") (url . "https://example.com/bazqux")))))) "contributors = [\n \"Foo Bar <foo@example.com>\",\n { email = \"bazqux@example.com\", name = \"Baz Qux\", url = \"https://example.com/bazqux\" },\n]"
4 Discussion of Design and Future Plans
Here are a few caveats or "gotchas" that may be relevant to users. Please visit the GitHub repository and comment if these are issues of concern.
4.1 TOML and JSON
While TOML and JSON have slightly different intended purposes, both can naturally represent symbol-keyed hash tables. There are some slight differences between the two, with neither being a strict subset of the other. TOML maps specifically to a hash table, where JSON need not be. However, TOML’s specification includes dates as basic types and mandates support for infinity and NaN.
As a consequence, a tomlexpr is not guaranteed to satisify jsexpr?. Future plans are to eventually expand the library API to include a mechanism to provide jsexpr output, though individual users may want to consider how/if their application should handle non-JSON values.
4.2 Use of gregor
The TOML specification requires that dates and times can be represented separately or in combination, with millisecond (or greater) precision. These factors led to requiring the gregor library and using those structs instead of the base Racket date and related apparatus with custom machinery.
As generating these dates are part of parse-toml, this means that this library in its current state still adds gregor as a dependency, even if an application does not need all of the date and time features that the TOML spec allows.
4.3 Formatting of generated TOML strings
TOML permits many different ways to represent the same hash table. The formatting used for this version prioritizes simple testing and implementation. More options may eventually be exposed, but at this (early) stage, the default could change quite substantially.
4.4 Error messages for table conflicts
The current parser design allows for the error messages to include position information when a key has been defined multiple times. However, for tables, it only provides the table name (and not the in-file position) of the offending situation.