Files

2.9 KiB

wson

Rust implementation of the WSON text format and JBON binary format, with serde support.

Features

  • Serde API for ordinary acyclic Rust data:
    • text: wson::to_string, wson::from_str
    • binary JBON: wson::to_vec, wson::from_slice
  • Graph API for WSON reference/cycle support:
    • text references: (0){"child":$0}
    • binary references: marker 0x06 for ids and 0x05 for references
  • Java-compatible defaults from net.woggioni:wson:
    • sorted objects (BTreeMap)
    • parser max_depth = 1_048_576
    • serialize_references = false unless enabled
  • Signed zigzag LEB128 and byte-reversed double encoding compatible with net.woggioni:jwo.

Quick start

[dependencies]
serde = { version = "1.0", features = ["derive"] }
wson = "0.1"
use serde::{Deserialize, Serialize};

#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Config {
    name: String,
    enabled: bool,
    retries: i64,
}

fn main() -> wson::Result<()> {
    let value = Config {
        name: "worker".to_string(),
        enabled: true,
        retries: 3,
    };

    let text = wson::to_string(&value)?;
    assert_eq!(text, r#"{"enabled":true,"name":"worker","retries":3}"#);
    let decoded: Config = wson::from_str(&text)?;
    assert_eq!(decoded, value);

    let bytes = wson::to_vec(&value)?;
    let decoded: Config = wson::from_slice(&bytes)?;
    assert_eq!(decoded, value);

    Ok(())
}

References and cycles

Serde's data model is acyclic, so cyclic/shared WSON values use the graph API:

use wson::{Config, Node};

fn main() -> wson::Result<()> {
    let cfg = Config {
        serialize_references: true,
        ..Config::default()
    };

    let graph = wson::text::parse_str("(0){\"child\":$0,\"id\":25}", &cfg)?;
    let root = graph.root();
    let child = match graph.node(root) {
        Node::Object(entries) => *entries.get("child").unwrap(),
        _ => panic!("expected object"),
    };
    assert_eq!(root, child);

    let text = wson::text::dump_graph(&graph, &cfg)?;
    let jbon = wson::binary::dump_graph(&graph, &cfg)?;
    println!("{text} ({} JBON bytes)", jbon.len());
    Ok(())
}

Compatibility notes

  • WSON integers are signed 64-bit. u64 values above i64::MAX fail to serialize.
  • WSON floats are f64. Text output uses Java Double.toString-style formatting.
  • The text parser intentionally mirrors the Java parser's leniency: commas/colons are not strictly validated, and unknown characters are skipped.
  • The parser enforces Config::max_depth; dumpers do not limit depth, but cyclic graphs require serialize_references.
  • Object keys are sorted by default to match the Java default TreeMap object implementation.

Examples

cargo run --example serde_text
cargo run --example serde_jbon
cargo run --example graph_references

Development

cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo test

License

MIT