TOON Format for Rust
Token-Oriented Object Notation (TOON) is a compact, human-readable format designed for passing structured data to Large Language Models with significantly reduced token usage.
This crate provides the official, spec-compliant Rust implementation of TOON v2.0 with v1.5 optional features, offering both a library (toon-format) and a full-featured command-line tool (toon).
Quick Example
JSON (16 tokens, 40 bytes):
TOON (13 tokens, 28 bytes) - 18.75% token savings:
users[2]{id,name}:
1,Alice
2,Bob
Features
- Spec-Compliant: Fully compliant with TOON Specification v2.0
- v1.5 Optional Features: Key folding and path expansion
- Safe & Performant: Built with safe, fast Rust
- Serde Integration: Native support for
serde_json::Value - Powerful CLI: Full-featured command-line tool
- Strict Validation: Enforces all spec rules (configurable)
- 100% Test Coverage: 109 unit tests + 22 spec fixture tests passing
Installation
As a Library
As a CLI Tool
Library Usage
Basic Encode & Decode
use json;
use ;
API Reference
Encoding
encode(&value, &options) -> Result<String, ToonError>
Encode a serde_json::Value to TOON format.
use ;
use json;
let data = json!;
// Default encoding
let toon = encode?;
// items[3]: a,b,c
// Custom delimiter
let opts = new
.with_delimiter;
let toon = encode?;
// items[3|]: a|b|c
// Custom indentation
let opts = new
.with_indent;
let toon = encode?;
EncodeOptions
| Method | Description | Default |
|---|---|---|
with_delimiter(d) |
Set delimiter: Comma, Tab, or Pipe |
Comma |
with_indent(i) |
Set indentation (spaces only) | Spaces(2) |
with_spaces(n) |
Shorthand for Indent::Spaces(n) |
2 |
with_key_folding(mode) |
Enable key folding (v1.5) | Off |
with_flatten_depth(n) |
Set max folding depth | usize::MAX |
Decoding
decode(&input, &options) -> Result<Value, ToonError>
Decode TOON format to serde_json::Value.
use ;
let toon = "name: Alice\nage: 30";
// Default (strict) decode
let json = decode?;
// Non-strict mode (relaxed validation)
let opts = new
.with_strict;
let json = decode?;
// Disable type coercion
let opts = new
.with_coerce_types;
let json = decode?;
// With coercion: {"active": true}
// Without: {"active": "true"}
DecodeOptions
| Method | Description | Default |
|---|---|---|
with_strict(b) |
Enable strict validation | true |
with_coerce_types(b) |
Auto-convert strings to types | true |
with_expand_paths(mode) |
Enable path expansion (v1.5) | Off |
v1.5 Features
Key Folding (Encoder)
New in v1.5: Collapse single-key object chains into dotted paths to reduce tokens.
Standard nesting:
data:
metadata:
items[2]: a,b
With key folding:
data.metadata.items[2]: a,b
Example
use ;
use json;
let data = json!;
// Enable key folding
let opts = new
.with_key_folding;
let toon = encode?;
// Output: data.metadata.items[2]: a,b
With Depth Control
let data = json!;
// Fold only 2 levels
let opts = new
.with_key_folding
.with_flatten_depth;
let toon = encode?;
// Output:
// a.b:
// c:
// d: 1
Safety Features
Key folding only applies when:
- All segments are valid identifiers (
a-z,A-Z,0-9,_) - Each level contains exactly one key
- No collision with sibling literal keys
- Within the specified
flatten_depth
Keys like full-name, user.email (if quoted), or numeric keys won't be folded.
Path Expansion (Decoder)
New in v1.5: Automatically expand dotted keys into nested objects.
Compact input:
a.b.c: 1
a.b.d: 2
a.e: 3
Expanded output:
Example
use ;
let toon = "a.b.c: 1\na.b.d: 2";
// Enable path expansion
let opts = new
.with_expand_paths;
let json = decode?;
// {"a": {"b": {"c": 1, "d": 2}}}
Round-Trip Example
use ;
use json;
let original = json!;
// Encode with folding
let encode_opts = new
.with_key_folding;
let toon = encode?;
// → "user.profile.name: Alice"
// Decode with expansion
let decode_opts = new
.with_expand_paths;
let restored = decode?;
assert_eq!; // Perfect round-trip!
Quoted Keys Remain Literal
let toon = r#"a.b: 1
"c.d": 2"#;
let opts = new
.with_expand_paths;
let json = decode?;
// {
// "a": {"b": 1},
// "c.d": 2 ← quoted key preserved
// }
CLI Usage
Basic Commands
# Auto-detect from extension
# Force mode
# Pipe from stdin
|
|
Encode Options
# Custom delimiter
# Custom indentation
# Key folding (v1.5)
# Show statistics
Decode Options
# Pretty-print JSON
# Relaxed validation
# Disable type coercion
# Path expansion (v1.5)
Full Example
|
| | | | |
+======================================+
| | | | |
||
| ) | | | |
Test Coverage
Comprehensive Test Suite
- 109 Unit Tests: Core functionality, edge cases, error handling
- 22 Spec Fixture Tests: Official TOON spec compliance tests
- 11 decode fixtures (objects, arrays, primitives, validation)
- 11 encode fixtures (formatting, delimiters, arrays)
- 13 Key Folding Tests: v1.5 feature coverage
- 11 Path Expansion Tests: v1.5 feature coverage
- Integration Tests: Real-world scenarios
- Doc Tests: All examples in documentation tested
Running Tests
# Run all tests
# Run specific test suite
# With output
# Release mode
Error Handling
All operations return Result<T, ToonError> with descriptive error messages:
use ;
match decode_strict
Error Types
ParseError- Syntax errors with line/column infoLengthMismatch- Array length doesn't match headerTypeMismatch- Unexpected value typeInvalidStructure- Malformed TOON structureSerializationError/DeserializationError- Conversion failures
Examples
See the examples/ directory for more:
basic.rs- Simple encode/decodeoptions.rs- Custom configurationfolding.rs- Key folding examplesexpansion.rs- Path expansion examplescli_usage.sh- CLI examples
Resources
- 📖 TOON Specification v2.0
- 📦 Crates.io Package
- 📚 API Documentation
- 🔧 Main Repository (JS/TS)
- 🎯 Benchmarks & Performance
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
Development
# Clone the repository
# Run tests
# Run lints
# Format code
# Build docs
License
MIT License © 2025-PRESENT Johann Schopplich and Shreyas K S