No description
Find a file
Tu Nombre 33dbd41ce8 update
2025-08-29 18:35:16 +02:00
example refactor Table 2023-01-23 20:12:26 +01:00
src update 2025-08-29 18:33:23 +02:00
.gitignore update 2025-08-29 18:34:33 +02:00
build.zig Refactor Table 2023-01-22 21:39:50 +01:00
LICENSE first commit 2022-09-19 22:42:52 +02:00
README.md refactor Table 2023-01-23 20:12:26 +01:00

toml

Warning: Work in progress...

A TOML(v1.0.0) parser written in Zig.

the goal is a full implementation of TOML v1.0.0

The library passes the TOML test suite.

Because zig does not have datetime types currently the datetime types are saved as strings. Suggestions are welcome.

Examples

Simple key value example:

const std = @import("std");
const toml = @import("toml");

var allocator = std.heap.page_allocator;
const stdout = std.io.getStdOut().writer();

pub fn main()!void {
    const input = 
        \\a = 12345
        \\b = true
        \\c = "Hello"
    ;
    
    var vt = try toml.parse(allocator, input, null);
    defer vt.deinit();

    try stdout.print("a={}\n", .{vt.root.keys.get("a").?.Integer});
    try stdout.print("b={}\n", .{vt.root.keys.get("b").?.Boolean});
    try stdout.print("c={s}\n", .{vt.root.keys.get("c").?.String});
}

Table example:

const std = @import("std");
const toml = @import("toml");

var allocator = std.heap.page_allocator;
const stdout = std.io.getStdOut().writer();

pub fn main()!void {
    const input = 
        \\[table1]
        \\a = 1
        \\[table2]
        \\a = "one"
    ;

    var vt = try toml.parse(allocator, input, null);
    try stdout.print("table1.a={}\n", .{vt.root.keys.get("table1").?.Table.keys.get("a").?.Integer});
    try stdout.print("table2.a={s}\n", .{vt.root.keys.get("table2").?.Table.keys.get("a").?.String});
}

The third parameter pos of parse function is a structure pointer:

    pub const Position = struct {
        row: usize = 0,
        col: usize = 0,
    };

Contains the current row and column, in case of error it contains the row and column where the error occurred. It can be null.

Error example:

const std = @import("std");
const toml = @import("toml");

var allocator = std.heap.page_allocator;
const stdout = std.io.getStdOut().writer();

pub fn main()!void {
    const input = 
        \\a = 123@45
        \\b = true
        \\c = "Hello"
    ;

    var pos = toml.Position{};
    
    var vt: ?toml.ValueTree = toml.parse(allocator, input, &pos) catch |err| {
        std.log.err("{} at row {} col {}\n", .{err, pos.row, pos.col});
        return {};
    };

    if (vt) |t| {
        try stdout.print("a={}\n", .{t.root.keys.get("a").?.Integer});
        //...
    }
}

The table2json function returns a json that can be used with the std json library:

const std = @import("std");
const toml = @import("toml");

var allocator = std.heap.page_allocator;
const stdout = std.io.getStdOut().writer();

pub fn main()!void {
    const input = 
        \\pointers = [
        \\    {x = 25, y = 32, color = 'yellow'},
        \\    {x = 12, y = 83, color = 'red'},
        \\    {x = 333, y = 444, color = 'blue'},
        \\]
    ;

    const Data = struct {
        pointers: []struct {
            x: i32,
            y: i32,
            color: []u8,
        }
    };

    var vt = try toml.parse(allocator, input, null);
    var output = std.ArrayList(u8).init(allocator);
    defer {
        vt.deinit();
        output.deinit();
    }
    
    try toml.table2json(vt.root, output.writer(), false);
    var stream = std.json.TokenStream.init(output.items);
    const parsedData = try std.json.parse(Data, &stream, .{.allocator = allocator});
    defer std.json.parseFree(Data, parsedData, .{.allocator = allocator});
        
    for (parsedData.pointers) |p| {
        try stdout.print("x={} y={}, color={s}\n", .{p.x, p.y, p.color});
    }
}

If the third parameter type_value of the table2json function is true, the values will be in the format {"type": "{TTYPE}", "value": {TVALUE}}, this is the format used by the TOML test suite

Example program for test:

const std = @import("std");
const toml = @import("toml");
var allocator = std.heap.page_allocator;

pub fn main()!void {
    const input = try std.io.getStdIn().readToEndAlloc(allocator, 2048);
    var output = std.ArrayList(u8).init(allocator);
    var vt = try toml.parse(allocator, input, null);
    defer {
        allocator.free(input);
        output.deinit();
        vt.deinit();
    }
    
    try toml.table2json(vt.root, output.writer(), true);
    try std.io.getStdOut().writer().writeAll(output.items);
}