Crous
A compact, canonical binary serializer and human-readable alternative to JSON, written in Rust.
Overview
Crous is a production-grade binary serialization format that provides:
- Compact binary encoding — 2×–5× smaller than equivalent JSON
- Human-readable text notation — unique syntax with deterministic binary mapping
- Zero-copy decoding — borrow directly from input buffers
- Schema evolution — stable field IDs, unknown-field skipping
- Streaming support — block-framed format with per-block checksums
- Pluggable compression — zstd/snappy per-block, with plugin trait
- Cross-language FFI — clean C bindings with documented ownership
Quick Start
use ;
// Encode
let value = Object;
let mut encoder = new;
encoder.encode_value.unwrap;
let bytes = encoder.finish.unwrap;
// Decode (zero-copy)
let mut decoder = new;
let decoded = decoder.decode_next.unwrap;
assert_eq!;
Human-Readable Syntax
{
name: "Alice";
age: 30;
tags: ["admin", "user"];
config: {
theme: "dark";
notifications: true;
};
avatar: b64#iVBORw0KGgo=;
}
Workspace Crates
| Crate | Description |
|---|---|
crous-core |
Encoder/decoder, block framing, Value types |
crous-derive |
#[derive(Crous)] proc-macro with stable field IDs |
crous-io |
Async Tokio adapters, framed streams |
crous-cli |
CLI: inspect, pretty-print, convert |
crous-compression |
Pluggable zstd/snappy compression |
crous-ffi |
C FFI bindings |
crous-simd |
NEON/SSE2 SIMD acceleration (byte scanning) |
Python Implementation
A pure-Python implementation is included in python/crous/, providing
full encode/decode compatibility with the Rust implementation:
# Encode
=
# Decode
=
# {'name': 'Alice', 'age': 30, 'active': True}
# Human-readable text format
=
Cross-language interop verified: Rust-encoded files decode correctly in Python and vice versa.
# Run Python tests
&&
CLI Usage
# Install
# Convert JSON to Crous
# Pretty-print a Crous file
# Inspect block layout
# Convert back to JSON
# Quick benchmark
Derive Macro
use ;
let alice = Person ;
// Encode
let value = alice.to_crous_value;
let mut encoder = new;
encoder.encode_value.unwrap;
let bytes = encoder.finish.unwrap;
Binary Format Summary
File: [Header 8B] [Block]* [Trailer Block]
Header: "CROUSv1" (7B) | flags (1B)
Block: type(1B) | length(varint) | compression(1B) | checksum(8B) | payload
Wire types: Null, Bool, VarUInt (LEB128), VarInt (ZigZag+LEB128), Fixed64, LenDelimited, StartObject, EndObject, StartArray, EndArray, Reference.
Build & Test
Fuzzing
Performance
Crous vs JSON (serde_json) on Apple Silicon (M-series):
| Payload | Crous size | JSON size | Ratio | Decode speed |
|---|---|---|---|---|
| Small object | 118 B | 90 B | 1.31× | 4× faster |
| 100 users nested | 9.8 KB | 10.3 KB | 0.95× | ~2× faster |
| 10K integers | 29.9 KB | 52.8 KB | 0.57× | ~3× faster |
| 64 KB binary | 65.6 KB | 87.4 KB | 0.75× | ~10× faster |
Crous decode throughput: 1.2 GiB/s for small objects.
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.