Skip to content

konimarti/toml.c3l

Repository files navigation

TOML parser for C3

TOML v1.0 in C3.

It also comes with a TOML validator CLI tool. The validator tool can be compiled with c3c build tomlv. tomlv will validate a TOML config file that is read from stdin.

Usage

TOML config files can be parsed from a String, a InStream (such as File) or directly from a file name.

Read data from String s:

TomlData td = toml::from_string(s)!;
defer td.free();

Read data from InStream in:

TomlData td = toml::from_stream(in)!;
defer td.free();

Read data directly from a file name:

TomlData td = toml::from_file("test.toml")!;
defer td.free();

To obtain a config value from the TOML tables, use the TomlData.get function (or the [] operator) and provide the table and value names in a dotted-key notation.

For example, the color value from the TOML config

[fruit]
color = 0x3AA832

can be obtained with td.get("fruit.color") or td["fruit.color"]. The return value is of type std::collections::Object*.

Error handling

If an error is encountered during the parsing, the line and column positions together with an error description are printed on stderr:

$ 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_SEPARATOR

The error output can be deactivated by setting the bool argument verbose to false in the toml::from_* functions.

Unmarshal TOML into struct

The parsed TOML data can also be unmarshalled into a custom struct with the TomlData.unmarshal macro:

TomlData td = toml::from_string(s)!!;
defer td.free();

MyConfig config;
td.unmarshal(&config)!!;

For a more detailed example, see below.

Installation

Clone the repository with git clone http://github.com/konimarti/toml.c3l to the ./lib folder of your C3 project and add the following to project.json:

{
    "dependency-search-paths": [ "lib" ],
    "dependencies": [ "toml" ]
}

If you didn't clone it into the lib folder, adjust your dependency-search-paths accordingly.

Running tests

Install the toml-test binary from the official repo:

go install github.com/toml-lang/toml-test/cmd/toml-test@v1.6.0

Then compile tomlv:

c3c bulid tomlv

and run the test suite as follows:

toml-test -- build/tomlv -j

to verify that all tests pass.

Examples

Parse TOML from String

module app;

import std::io;
import toml;

fn void main()
{	
	String s = ` 
    # toml config file
	title = "TOML example"
	[database]
	ports = [8000, 8001, 8002]`;

	TomlData td = toml::from_string(s)!!;
	defer td.free();

	io::printfn("title: %s", td.get("title")!!);
	io::printfn("ports: %s", td.get("database.ports")!!);
}
// Output:
// title: "TOML example"
// ports: [8000,8001,8002]

Parse TOML and decode to struct

module tomltest;

import std::io;
import toml;

struct Fruit
{
	String name;
	int color;
	double price;
	int items;
	bool fresh;
}

struct TomlConfig
{
	String title;
	Fruit fruit;
}

fn void main()
{	
	String s = `
	title = "TOML example"

	[fruit]
	name = "apple"
	color = 0xbeef
	price = 1.32
	items = 4
	fresh = true`;

	TomlData td = toml::from_string(s)!!;
	defer td.free();

	TomlConfig config;
	td.unmarshal(&config)!!;
	
	io::printn(config);
}
// Output:
// { title: TOML example, fruit: { name: apple, color: 48879, price: 1.320000, items: 4, fresh: true } }

About

TOML parser for C3 with reflection

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published