koda-rs 0.1.0

Rust implementation of KODA format: compact, deterministic text and binary serialization compatible with koda-go
Documentation

koda-rs

Crates.io Documentation License: MIT

Rust implementation of KODA (Compact Object Data Architecture): a compact, deterministic format for structured data with both a human-friendly text form and a binary wire format compatible with koda-go.

Features

  • Parse KODA text into a dynamic Value (objects, arrays, scalars)
  • Stringify Value back to text (deterministic, sorted keys)
  • Encode Value to binary (Go-compatible, deterministic)
  • Decode binary to Value
  • Streaming parserparse_reader for bounded-memory parsing of large inputs
  • Structured errorsKodaError with parse position and encode/decode messages
  • Deterministic outputBTreeMap for object keys; binary layout matches koda-go

Optional Features

Feature Description
parallel Use rayon for parallel decoding of large arrays and objects via decode_parallel
serde Serde support: from_str / to_string for any Serialize/Deserialize type

Quick Start

Add to Cargo.toml:

[dependencies]
koda-rs = "0.1"

Example:

use koda_rs::{parse, stringify, encode, decode, Value};

fn main() -> Result<(), koda_rs::KodaError> {
    let text = r#"
        name: "my-app"
        version: 1
        enabled: true
    "#;

    let value = parse(text)?;
    let back_to_text = stringify(&value);

    let bytes = encode(&value)?;
    let decoded = decode(&bytes)?;
    assert_eq!(value, decoded);

    Ok(())
}

Data Model

pub enum Value<'a> {
    Null,
    Bool(bool),
    Number(f64),
    String(Cow<'a, str>),
    Array(Vec<Value<'a>>),
    Object(BTreeMap<Cow<'a, str>, Value<'a>>),
}

Objects use BTreeMap for deterministic key order.

Text Format

  • Key-value: key: value (commas optional; newline or comma can separate fields)
  • Strings: "..." with \", \\, \n, \r, \t
  • Numbers: integers and floats (e.g. 1, 3.14)
  • Booleans: true, false
  • Null: null
  • Objects: { key: value, ... } or a key-value block at root
  • Arrays: [ value, ... ]
  • Line comments: // ...

Binary Format

  • Magic: KODA (4 bytes), version (1 byte)
  • Dictionary: u32 count, then for each key u32 length + UTF-8 bytes (keys unique, sorted lexicographically)
  • Root value with type tags: null, false, true, integer (8-byte big-endian), float (8-byte IEEE 754), string (4-byte length + UTF-8), array, object (key = dictionary index)
  • Compatible with koda-go for encode/decode

Performance Notes

  • Binary is typically smaller than JSON for repetitive structures (keys stored once in dictionary)
  • Text is human-friendly with minimal syntax overhead
  • Enable the parallel feature for faster decoding of large arrays/objects (e.g. 10k+ elements)
  • Use parse_reader for very large inputs to keep memory bounded (chunked streaming)

Comparison with JSON

Aspect JSON KODA (this crate)
Text Ubiquitous, many tools Key-value style, minimal syntax
Binary Not standard Yes, with key dictionary
Key reuse Repeated in every field Once per key in dictionary (binary)
Determinism Order-dependent Deterministic (binary and stringify)
Interop Universal Rust + Go (binary); custom text

Use JSON when you need maximum interoperability; use KODA when you want a compact, deterministic binary format and a simple text format in Rust (and Go).

Benchmarks

Run all benchmarks:

cargo bench
  • Decode (binary) — Sequential and (with parallel feature) parallel decoding:

    cargo bench --bench decode
    cargo bench --bench decode --features parallel
    
  • Koda vs JSON — Serialization and parsing compared to serde_json (requires serde feature):

    cargo bench --features serde --bench koda_vs_json
    

License

MIT