A TOML v1.0.0 parser and validator for the C3 programming language.
- Implements the full TOML v1.0.0 specification.
- Decodes TOML data into structs (example below).
- Fully passes the official toml-test suite.
- Includes a command-line TOML validator tool
tomlvfor syntax checking.
TOML configuration files can be parsed from a String, an InStream (e.g.
File), or directly from a file path.
Read data from String s:
TomlData config = toml::from_string(s)!;
Read data from InStream in:
TomlData config = toml::from_stream(in)!;
Read data directly from a file path:
TomlData config = toml::from_file("test.toml")!;
The toml::from_* functions accept two additional arguments: a memory
allocator and a flag for error verbosity. The default allocator is mem.
To access a configuration value, use TomlData.get (or the [] operator) with
dotted-key notation.
For example, given:
[fruit]
color = 0x3AA832you can read the hex value with:
config.get("fruit.color");
or: config["fruit.color"];
Both return a pointer of type std::collections::Object*.
When parsing errors occur, detailed diagnostics are printed to stderr,
including the line, column and error type:
$ echo "\"a quoted key without a value\"" | build/tomlv
TOML ERROR -- Line 1, Col 31: expected '='
TOML ERROR -- Line 1, Col 31: parser::MISSING_KEYVAL_SEPARATOR
"a quoted key without a value"
^
Invalid TOML: parser::MISSING_KEYVAL_SEPARATORError messages can be silenced by setting the optional verbose to false in
any of the toml::from_* functions.
Parsed TOML data can be directly decoded into a user-defined struct MyStructusing
toml::decode{MyStruct}:
TomlData toml = toml::from_string(s)!!;
MyConfig my_config = toml::decode{MyConfig}(toml)!!;Decoding into arrays is currently only implemented for fixed-sized arrays of
type Object*.
For a more detailed example, see below.
Add the library as a submodule to your C3 project:
git submodule add http://github.com/konimarti/toml.c3l lib
Then update your project.json to include:
{
"dependency-search-paths": [ "lib" ],
"dependencies": [ "toml" ]
}Adjust dependency-search-paths if you keep the submodule in a different
directory.
To verify correctness, use the official TOML test suite:
go install github.com/toml-lang/toml-test/cmd/toml-test@v1.6.0
c3c build tomlv
toml-test -- build/tomlv -jmodule app;
import std::io, toml;
fn void main() => @pool()
{
String s = `
# toml comment
title = "TOML example"
[database]
ports = [8000, 8001, 8002]`;
TomlData cfg = toml::from_string(s, tmem)!!;
io::printfn("title: %s", cfg.get("title")!!);
io::printfn("ports: %s", cfg.get("database.ports")!!);
}
// Output:
// title: "TOML example"
// ports: [8000,8001,8002]
module tomltest;
import std::io, toml;
struct Fruit
{
String name;
int color;
double price;
bool fresh;
}
struct TomlConfig
{
String title;
Fruit fruit;
}
fn void main()
{
String s = `
title = "TOML example"
[fruit]
name = "apple"
color = 0xbeef
price = 1.32
fresh = true`;
TomlData toml = toml::from_string(s)!!;
defer toml.free();
TomlConfig my_config = toml::decode{TomlConfig}(toml);
io::printn(my_config);
}
// Output:
// { title: TOML example, fruit: { name: apple, color: 48879, price: 1.320000, fresh: true } }