# toon-encode
Minimal [TOON](https://toonformat.dev/) encoder for Rust — Token-Oriented Object Notation for LLM output.
TOON is a compact, human-readable encoding of JSON data that reduces token consumption by 30-50% for list-heavy responses. Field names are declared once in tabular headers instead of repeated on every row.
## Usage
```rust
use serde::Serialize;
#[derive(Serialize)]
struct Item { name: String, value: i32 }
let items = vec![
Item { name: "alpha".into(), value: 1 },
Item { name: "beta".into(), value: 2 },
];
// From any Serialize type
let toon = toon_encode::to_toon_string(&items).unwrap();
// Output:
// [2]{name,value}:
// alpha,1
// beta,2
```
You can also encode a `serde_json::Value` directly:
```rust
let value = serde_json::json!({
"status": "ok",
"items": [
{"file": "main.rs", "kind": "fn", "lines": 25},
{"file": "lib.rs", "kind": "mod", "lines": 10},
]
});
let toon = toon_encode::encode_toon(&value, 0);
// Output:
// status: ok
// items:
// [2]{file,kind,lines}:
// main.rs,fn,25
// lib.rs,mod,10
```
## When TOON helps
TOON is most effective for **flat tabular arrays** — uniform objects with only primitive fields:
| JSON | 51 bytes |
| TOON | 28 bytes (**-45%**) |
For nested or content-heavy responses, TOON may be larger than JSON.
## Encoding rules
- **Objects**: YAML-like `key: value` with 2-space indentation
- **Uniform arrays of objects**: Tabular `[N]{field1,field2,...}:` header + CSV rows
- **Primitive arrays**: List with `- value` per line
- **Strings**: Quoted when containing `,`, `:`, `"`, `\`, `[`, `]`, `{`, `}`, `\n`, `\r`, `\t`, or starting with `-`
## API
```rust
/// Encode any Serialize type as TOON.
pub fn to_toon_string<T: serde::Serialize>(value: &T) -> Result<String, serde_json::Error>;
/// Encode a serde_json::Value as TOON at the given indentation depth.
pub fn encode_toon(value: &serde_json::Value, depth: usize) -> String;
```
## License
MIT