serde_toon2
Serde-compatible serializer/deserializer for TOON (Token-Oriented Object Notation), a line-oriented, indentation-based format that encodes the JSON data model.
Why build another TOON parser?
None of the other TOON crates (at the time of writing this) implement the TOON spec in its entirety. I needed a crate that actually worked as expected, so I've built one.
Fixtures in tests/fixtures will be kept up to date with official tests.
Installation
[]
= "0.1.0"
= { = "1.0", = ["derive"] }
Format Overview
TOON encodes JSON structures using indentation instead of braces:
user:
id: 123
name: Ada
items[2]: a,b
Equivalent JSON:
Characteristics:
- Indentation-based structure: Objects use 2-space indentation (configurable)
- Minimal quoting: Strings quoted only when ambiguous (reserved words, delimiters, special syntax)
- Array headers: Declare length and optional field list:
[3]or[3 name,age] - Three delimiters: Arrays use comma (default), tab, or pipe delimiters
Serialization
use Serialize;
use ;
let user = User ;
// Default options
let toon = to_string?;
// Output: "id: 42\nname: Ada"
// Custom options
let opts = EncoderOptions ;
let toon = to_string_with_options?;
Encoder Options
Deserialization
use Deserialize;
use ;
let toon = "id: 42\nname: Ada";
let user: User = from_str?;
// Strict mode validation
let opts = DecoderOptions ;
let user: User = from_str_with_options?;
Decoder Options
API
Serialization
to_string<T: Serialize>(value: &T) -> Result<String>to_string_with_options<T: Serialize>(value: &T, options: &EncoderOptions) -> Result<String>to_vec<T: Serialize>(value: &T) -> Result<Vec<u8>>to_vec_with_options<T: Serialize>(value: &T, options: &EncoderOptions) -> Result<Vec<u8>>to_writer<W: Write, T: Serialize>(writer: W, value: &T) -> Result<()>to_writer_with_options<W: Write, T: Serialize>(writer: W, value: &T, options: &EncoderOptions) -> Result<()>
Deserialization
from_str<'a, T: Deserialize<'a>>(s: &'a str) -> Result<T>from_str_with_options<'a, T: Deserialize<'a>>(s: &'a str, options: &DecoderOptions) -> Result<T>from_slice<'a, T: Deserialize<'a>>(v: &'a [u8]) -> Result<T>from_slice_with_options<'a, T: Deserialize<'a>>(v: &'a [u8], options: &DecoderOptions) -> Result<T>from_reader<R: Read, T: DeserializeOwned>(reader: R) -> Result<T>from_reader_with_options<R: Read, T: DeserializeOwned>(reader: R, options: &DecoderOptions) -> Result<T>
Error Handling
Strongly-typed errors with location information:
Errors include line/column location when available:
Invalid syntax at line 5, column 12
Value Type
Generic value type for dynamic content:
pub type Map<K, V> = IndexMap; // Preserves insertion order
Format Examples
Objects
name: Ada
age: 42
active: true
Nested Objects
user:
name: Ada
profile:
bio: Programmer
location: London
Arrays (comma-delimited)
tags[3]: rust,serde,parser
Arrays (vertical)
tags[3]:
rust
serde
parser
Arrays of Objects
users[2]:
name: Ada
age: 42
---
name: Bob
age: 35
Arrays with Field Lists
users[2 name,age]:
Ada,42
Bob,35
Tab-Delimited Arrays
scores[3] : 95 87 92
Pipe-Delimited Arrays
paths[2]|: /usr/bin|/usr/local/bin
Dependencies
serde1.0 - Serialization frameworkindexmap2.0 - Order-preserving maps
License
MIT