jassielof/ztoon
A Zig implementation of the TOON (Token-Oriented Object Notation) format, version 1.4.
A Zig implementation of the TOON (Token-Oriented Object Notation) format, version 1.4.
TOON is a line-oriented, indentation-based text format that encodes the JSON data model with explicit structure and minimal quoting. It's particularly efficient for arrays of uniform objects, providing a more compact and readable alternative to JSON for structured data.
See the full specification for details.
[N]{field1,field2}: format for uniform object arrays\t), and pipe (|) support[N<delim>]Requires Zig 0.15.2 or later:
zig build
The binary will be available at ./zig-out/bin/ztoon.
Encode JSON to TOON:
echo '{"name": "Alice", "age": 30}' | ./zig-out/bin/ztoon encode
Output:
name: Alice
age: 30
Decode TOON to JSON:
echo 'name: Alice
age: 30' | ./zig-out/bin/ztoon decode
Output:
{
"name": "Alice",
"age": 30
}
From files:
./zig-out/bin/ztoon encode input.json
./zig-out/bin/ztoon decode input.toon
const std = @import("std");
const toon = @import("ztoon");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
// Create a value
var obj = std.StringHashMap(toon.Value).init(allocator);
defer obj.deinit();
try obj.put("name", toon.Value{ .string = "Alice" });
try obj.put("age", toon.Value{ .number = 30 });
const value = toon.Value{ .object = obj };
defer value.deinit(allocator);
// Encode to TOON
const encoded = try toon.encode(allocator, value, .{});
defer allocator.free(encoded);
std.debug.print("TOON: {s}\n", .{encoded});
// Decode from TOON
var decoded = try toon.decode(allocator, encoded, .{});
defer decoded.deinit(allocator);
}
{"name": "Alice", "age": 30, "active": true}
↓
name: Alice
age: 30
active: true
{"user": {"name": "Alice", "settings": {"theme": "dark"}}}
↓
user:
name: Alice
settings:
theme: dark
{"items": [
{"sku": "A1", "qty": 2, "price": 9.99},
{"sku": "B2", "qty": 1, "price": 14.5}
]}
↓
items:[2]{sku,price,qty}:
A1,9.99,2
B2,14.5,1
{"users": [
{"name": "Alice", "role": "admin"},
{"name": "Bob", "role": "dev"}
]}
↓
users:[2|]{name|role}:
Alice|admin
Bob|dev
{"items": [1, 2, 3, 4, 5]}
↓
items[5]: 1,2,3,4,5
{"users": [{"name": "Alice", "id": 1}, {"name": "Bob", "id": 2}]}
↓
users[2]:
-
name: Alice
id: 1
-
name: Bob
id: 2
# in array headers) - parsing supported, encoding optionalspec/tests/fixtures/To continue improving this implementation:
spec/tests/fixtures/ for full spec complianceCurrently tested manually with various inputs. Run some quick tests:
# Test nested objects
echo '{"a":1,"b":{"c":2}}' | ./zig-out/bin/ztoon encode | ./zig-out/bin/ztoon decode
# Test tabular arrays
echo '{"items":[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"}]}' | ./zig-out/bin/ztoon encode
# Test with different delimiters
printf 'items:[2|]{name|role}:\n Alice|admin\n Bob|dev' | ./zig-out/bin/ztoon decode