nearest
Self-relative pointers for Rust. Clone is memcpy.
Store entire data graphs — trees, DAGs, linked lists — in a single contiguous
byte buffer where every internal pointer is a 4-byte i32 offset relative to
its own address. Cloning a region is a plain memcpy with zero fixup.
Serialization is as_bytes(). Mutation is compile-time safe.
Quick look
use ;
// Define recursive types with derive — no boilerplate.
// Build: (1 + 2)
let region = new;
// Read — Region<T>: Deref<Target = T>
match &*region
// Clone is memcpy — self-relative offsets just work.
let cloned = region.clone;
assert_eq!;
Why nearest?
Traditional Rust data structures use heap pointers. Cloning walks the entire
graph. Serialization requires a framework. Moving data between threads means
Arc overhead or deep copies.
nearest sidesteps all of this. A Region<T> is a flat byte buffer that you
can:
- Clone with
memcpy(no pointer fixup) - Serialize with
as_bytes()/ deserialize withfrom_bytes()(no schema, no codegen) - Send across threads or processes (it's just bytes)
- Mutate safely through branded sessions (ghost-cell pattern, zero runtime cost)
- Compact with
trim()to reclaim dead bytes after mutations
Features at a glance
| Feature | How |
|---|---|
| Derive-driven construction | #[derive(Flat)] generates make() builders with zero boilerplate |
| Self-relative pointers | Near<T> — 4-byte NonZero<i32> offset, Deref<Target = T> |
| Inline linked lists | NearList<T> — segmented list with O(1) prepend/append, indexing, iteration |
| Compile-time safe mutation | Branded Session + Ref tokens — no Ref can escape or cross sessions |
| Region compaction | trim() deep-copies only reachable data, reclaiming dead bytes |
no_std support |
Works without alloc; use FixedBuf<N> for fully stack-based regions |
| Serialization | as_bytes() / from_bytes() with validation; optional serde feature |
| Miri-validated | All unsafe code tested under Miri with permissive provenance |
Examples
Expression trees
Recursive types work naturally — Near<Expr> is a 4-byte self-relative pointer:
use ;
// (2 + 3) * 10 = 50
let region = new;
assert_eq!;
Mutation via branded sessions
Sessions use a ghost-cell pattern — Ref tokens are branded with a unique
lifetime so they can't escape the closure or be used in another session.
All checked at compile time, zero runtime cost:
use ;
let mut region = new;
region.session;
assert_eq!;
assert_eq!; // [4, 6]
assert_eq!;
Stack-only regions (no_std)
Use FixedBuf<N> for zero-heap construction — ideal for embedded or real-time:
use ;
let region: =
new_in;
assert_eq!;
assert_eq!;
Composing regions
Build sub-trees as separate regions, then compose them with references:
use ;
// Build children independently.
let child_a = new;
let child_b = new;
// Compose: &*Region<T> implements Emit<T>.
let tree = new;
assert_eq!;
assert_eq!;
// The entire tree is one contiguous buffer.
// Clone is still just memcpy.
let cloned = tree.clone;
assert_eq!;
How it works
Region<T> buffer layout:
[ Root T fields | Near<U> targets | NearList segments | ... ]
^ ^
byte 0 |
offset ───┘ (i32, relative to the Near<U> field's own address)
-
Construction:
Region::new(T::make(...))writes values into a contiguous buffer.Near<T>fields storei32offsets pointing forward to their targets.NearList<T>stores a head offset + length. -
Reading:
Region<T>: Deref<Target = T>.Near<T>: Deref<Target = T>— resolves by adding the stored offset to its own address. -
Mutation:
region.session(|s| { ... })opens a branded session. All writes are append-only — new data goes at the end, old offsets are patched. Dead bytes accumulate but are never read. -
Compaction:
region.trim()deep-copies only reachable data into a fresh buffer, eliminating dead bytes.
Comparison
| nearest | rkyv | FlatBuffers | bumpalo | |
|---|---|---|---|---|
| Self-relative pointers | i32 offsets |
relative pointers | u32 offsets |
no (heap ptrs) |
| Clone = memcpy | yes | no (absolute ptrs when deserialized) | n/a | no |
| Safe mutation | branded sessions | read-only archived data | read-only | &mut |
| Compaction | trim() |
no | no | reset only |
| Construction | #[derive(Flat)] |
#[derive(Archive)] |
schema codegen | manual |
no_std |
yes | yes | yes | yes |
Getting started
Requires nightly Rust (nightly-2026-02-10) for #![feature(offset_of_enum)].
[]
= "0.4"
See the API documentation for full reference, and
the examples/ directory for complete runnable programs:
expr.rs— Expression tree evaluator with recursiveNear<Expr>json.rs— JSON document model with heterogeneous enumsecs.rs— Entity-component system with physics, filtering, spawningfsm.rs— Finite state machine on a stack-onlyFixedBuffs.rs— Virtual file system with region composition and grafting
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.