| Crates.io | json2toon_rs |
| lib.rs | json2toon_rs |
| version | 0.2.0 |
| created_at | 2025-11-13 20:35:34.623977+00 |
| updated_at | 2025-11-13 21:22:48.348819+00 |
| description | Fast, bidirectional JSON to TOON converter with full TOON v2.0 specification compliance |
| homepage | https://github.com/anperrone/json2toon_rs |
| repository | https://github.com/anperrone/json2toon_rs |
| max_upload_size | |
| id | 1931838 |
| size | 99,703 |
Fast, optimized JSON to TOON format converter based on the TOON v2.0 specification.
TOON (Token-Oriented Object Notation) is a line-oriented, indentation-based text format that encodes JSON data with explicit structure and minimal quoting. It's particularly efficient for:
Add to your Cargo.toml:
[dependencies]
json2toon_rs = "0.1.0"
use json2toon_rs::{encode, EncoderOptions};
use serde_json::json;
fn main() {
let data = json!({
"users": [
{"id": 1, "name": "Alice", "active": true},
{"id": 2, "name": "Bob", "active": false}
]
});
let toon = encode(&data, &EncoderOptions::default());
println!("{}", toon);
}
Output:
users[2]{id,name,active}:
1,Alice,true
2,Bob,false
use json2toon_rs::{decode, DecoderOptions, DecodeError};
fn main() {
let toon = "users[2]{id,name,active}:\n 1,Alice,true\n 2,Bob,false";
let json = decode(toon, &DecoderOptions::default()).unwrap();
println!("{}", serde_json::to_string_pretty(&json).unwrap());
// Example of error handling
let invalid_toon = "tags[2]: one,two,three";
let result = decode(invalid_toon, &DecoderOptions::default());
assert!(matches!(result, Err(DecodeError::ArrayLengthMismatch { .. })));
}
use json2toon_rs::{encode, decode, EncoderOptions, DecoderOptions, DecodeError};
use serde_json::json;
fn main() {
let original = json!({"name": "Alice", "age": 30});
// Encode to TOON
let toon = encode(&original, &EncoderOptions::default());
// Decode back to JSON
let decoded = decode(&toon, &DecoderOptions::default()).unwrap();
assert_eq!(original, decoded); // Perfect round-trip!
}
let data = json!({
"name": "Alice",
"age": 30,
"active": true
});
TOON output:
name: Alice
age: 30
active: true
let data = json!({
"user": {
"id": 123,
"name": "Bob"
}
});
TOON output:
user:
id: 123
name: Bob
let data = json!({
"tags": ["admin", "user", "dev"]
});
TOON output:
tags[3]: admin,user,dev
Arrays of uniform objects with primitive values are automatically formatted as tables:
let data = json!({
"items": [
{"sku": "A1", "qty": 2, "price": 9.99},
{"sku": "B2", "qty": 1, "price": 14.50}
]
});
TOON output:
items[2]{sku,qty,price}:
A1,2,9.99
B2,1,14.5
Arrays with non-uniform content use expanded list format:
let data = json!({
"items": [
42,
"text",
{"key": "value"}
]
});
TOON output:
items[3]:
- 42
- text
- key: value
use json2toon_rs::{encode, Delimiter, EncoderOptions};
let options = EncoderOptions {
indent: 2,
delimiter: Delimiter::Tab,
};
let data = json!({
"items": [
{"id": 1, "name": "A"},
{"id": 2, "name": "B"}
]
});
let toon = encode(&data, &options);
TOON output (with tabs):
items[2 ]{id name}:
1 A
2 B
pub struct EncoderOptions {
/// Spaces per indentation level (default: 2)
pub indent: usize,
/// Document-wide delimiter (default: Comma)
pub delimiter: Delimiter,
}
pub enum Delimiter {
Comma, // Default
Tab, // \t
Pipe, // |
}
pub struct DecoderOptions {
/// Spaces per indentation level (default: 2)
pub indent: usize,
/// Strict mode - enforces counts, indentation, delimiter consistency (default: true)
pub strict: bool,
}
In strict mode, the decoder will:
This implementation follows the TOON v2.0 specification:
\\, \", \n, \r, \tRun the test suite:
cargo test
Run examples:
# Encoding examples
cargo run --example basic
# Decoding examples
cargo run --example decode
# Round-trip examples (encode + decode)
cargo run --example roundtrip
The decoder implements the complete TOON v2.0 specification:
[N], [N ], [N|])\\, \", \n, \r, \t)This project is licensed under the MIT License - see the LICENSE file for details.