sefer-region
100 % Rust typed handle-addressed store — no C / C++ libraries.
A thin typed membrane over slotmap:
values live in slotmap's dense, cache-friendly, always-compact backing store,
and every operation exposes only typed Handle<T> values — raw DefaultKeys
never escape the crate boundary. The original single-threaded face of
sefer-alloc, extracted as a
standalone crate.
Why?
slotmap's DefaultKey is untyped: a key from one map compiles against another
map of a different value type without error. sefer-region wraps it in
Handle<T> — a PhantomData<fn() -> T>-branded key — so the compiler rejects
cross-region handle confusion at the type level.
The differentiator for the pure-Rust audience: zero own unsafe —
#![forbid(unsafe_code)] at the top of this crate. The internal unsafe in
slotmap is its own, audited and battle-tested. No C / C++ libraries are pulled
in. With default-features = false the crate builds under no_std + alloc.
For users who want a typed slotmap-like handle store without pulling a full allocator stack.
Quick start
[]
= "0.1"
use ;
let mut region = new;
let h: = region.insert;
// I1: fresh handle resolves to the inserted value.
assert_eq!;
let v = region.remove.unwrap;
assert_eq!;
// I2 + I3: stale handle resolves to None.
assert!;
Invariants
- I1 — resolution: a fresh handle resolves via
getto the inserted value until it isremoved. - I2 — tombstone: after
remove(h),get(h)isNoneforever; a secondremove(h)is a no-opNone. - I3 — no ABA: a stale handle — one whose slot has since been reused for a
new value — never resolves to the new value.
slotmap'sDefaultKeycarries a generation counter bumped on removal, so the old handle fails the version check and yieldsNone. - I4 — accounting:
len()equals the number of live entries;is_empty()agrees. - I5 — drop-once: every live value is dropped exactly once — on
remove(returned to the caller) or onRegiondrop — never twice, never leaked.
SyncRegion (std feature, default-on)
SyncRegion<T> wraps Region<T> in a std::sync::RwLock for safe concurrent
access. It recovers from lock poison rather than propagating it (a panicked op
leaves the slotmap structurally intact).
use SyncRegion;
use Arc;
let sr: = new;
let sr2 = clone;
// One-shot convenience: no guard needed for single operations.
let h = sr.insert;
assert_eq!;
assert_eq!;
// Multi-op transaction: hold the write guard for atomicity.
// guard dropped, lock released
assert_eq!;
Feature flags
| Feature | Default | Effect |
|---|---|---|
std |
yes | Enables SyncRegion<T> and slotmap/std |
Disable default features for no_std + alloc (Region<T> + Handle<T> only):
= { = "0.1", = false }
Safety
#![forbid(unsafe_code)] at the top of this crate. The internal unsafe in
the slotmap dependency is its own, audited and battle-tested. This crate
contributes zero unsafe blocks and pulls in no C / C++ libraries.
License
Licensed under either of:
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
- Apache License, Version 2.0 (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
at your option.