prefix_arena/lib.rs
1#![no_std]
2//! Prefix-oriented arena utilities for caller-provided byte buffers.
3//!
4//! `prefix-arena` is a small `no_std` crate for working with a mutable byte
5//! buffer as a prefix-growing arena. It is designed for cases where allocation
6//! must stay explicit and bounded, such as embedded systems, protocol parsing,
7//! serializers, and staging temporary output into preallocated storage.
8//!
9//! The crate exposes two primary types:
10//!
11//! - [`PrefixArena`]: detaches prefixes from a backing buffer while keeping the
12//! remaining capacity available for later use.
13//! - [`StagingBuffer`]: writes into the current arena prefix and detaches only
14//! the bytes that were actually produced.
15//!
16//! # Examples
17//!
18//! Reserve a prefix directly from the arena:
19//!
20//! ```
21//! use prefix_arena::PrefixArena;
22//!
23//! let mut storage = [0u8; 8];
24//! let arena = PrefixArena::new(&mut storage);
25//!
26//! let prefix = arena
27//! .init_prefix_with(|buffer| {
28//! buffer[..3].copy_from_slice(b"abc");
29//! Ok::<usize, core::convert::Infallible>(3)
30//! })
31//! .unwrap();
32//!
33//! assert_eq!(prefix, b"abc");
34//! ```
35//!
36//! Stage bytes first and detach them once complete:
37//!
38//! ```
39//! use prefix_arena::{PrefixArena, StagingBuffer};
40//!
41//! let mut storage = [0u8; 16];
42//! let mut arena = PrefixArena::new(&mut storage);
43//! let mut staging = StagingBuffer::new(&mut arena);
44//!
45//! staging.extend_from_slice(b"hello").unwrap();
46//! staging.push_byte(b'!').unwrap();
47//!
48//! let written = staging.into_written_slice();
49//! assert_eq!(written, b"hello!");
50//! assert_eq!(arena.len(), 10);
51//! ```
52//!
53//! # Safety model
54//!
55//! The safe API only returns initialized `&[u8]` or `&mut [u8]` values after the
56//! caller reports how many bytes were written. Unsafe methods exist for treating
57//! the remaining arena bytes as initialized data; those methods require the
58//! caller to uphold initialization guarantees.
59mod prefix_arena;
60mod staging_buffer;
61
62pub use prefix_arena::{ArenaView, PrefixArena};
63pub use staging_buffer::{StagingBuffer, StagingBufferError};
64
65#[cfg(test)]
66extern crate std;