ringbuffer

A safe, no_std-compatible Rust crate providing fixed-size circular buffers for embedded and systems code.

Library
Cargo
v0.16.0
148stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
44/100Fair
Development Activity16
Maintenance20
Community60
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
71/100Good
Architecture82
Code Quality88
Innovation55
Learning Curve60

ringbuffer is a Rust crate that implements safe, fixed-size circular buffers with a shared API surface defined by the RingBuffer trait. It ships three interchangeable implementations: AllocRingBuffer (heap-allocated, fixed capacity), GrowableAllocRingBuffer (heap-allocated, can grow, backed by alloc::VecDeque), and ConstGenericRingBuffer (stack-allocated using const generics, no heap required). All three support push/pop, indexed access, iteration, and draining through a single unifying trait, so code can be written generically over whichever ringbuffer variant fits the deployment target.

The crate is #![no_std] by default, with the alloc feature (enabled by default) adding the two heap-backed variants; disabling it leaves only the const-generic, fully stack-based buffer, making the crate usable on embedded targets with no allocator. It has zero runtime dependencies, a declared MSRV of Rust 1.79, and enforces #![deny(missing_docs)] and #![deny(warnings)] at the crate root, so every public item is documented and the crate builds warning-free.

What You Get

  • Three ring buffer implementations sharing one RingBuffer trait API: AllocRingBuffer, GrowableAllocRingBuffer, and ConstGenericRingBuffer
  • no_std support by default, with the heap-backed variants gated behind an opt-out alloc feature for use on allocator-free embedded targets
  • Standard queue-like operations (enqueue/push, dequeue, drain, fill, fill_with, fill_default, clear) plus indexed access via Index/IndexMut
  • Iterator support, including a draining iterator and a mutable iterator with documented safety guarantees for iter_mut
  • Negative/wrap-aware indexing (get_signed) for referencing recently-pushed elements relative to the buffer’s tail
  • Zero runtime dependencies and a declared MSRV (Rust 1.79), keeping it lightweight to add to any project

Common Use Cases

  • Embedded and firmware code that needs a fixed-capacity FIFO buffer without a heap allocator, using ConstGenericRingBuffer
  • Streaming/telemetry pipelines that keep only the most recent N samples or log lines, overwriting the oldest entry once capacity is reached
  • Audio/DSP or sensor-processing code that needs a lock-free-friendly, fixed-size sliding window over incoming data
  • General application code that wants a growable ring buffer backed by VecDeque semantics via GrowableAllocRingBuffer without hand-rolling wraparound logic

Under The Hood

Architecture The crate is organized around one unsafe core trait, RingBuffer (in ringbuffer_trait.rs), which every concrete buffer implements: AllocRingBuffer and GrowableAllocRingBuffer (in src/with_alloc/) and ConstGenericRingBuffer (with_const_generics.rs). The trait defines raw-pointer-based ptr_len/ptr_capacity methods that implementors back with safe wrappers, letting the shared default methods (is_empty, is_full, drain, fill, fill_default) live in one place while each storage type only implements the primitives (enqueue, dequeue, indexing) specific to its allocation strategy. A separate SetLen trait factors out length-mutation so the alloc-backed and const-generic implementations can share iterator and drain logic without duplicating unsafe code; changing the core RingBuffer trait’s contract would ripple into all three implementations and their iterator types simultaneously, since they’re the trait’s sole consumers.

Tech Stack The crate targets stable Rust with a declared MSRV of 1.79 and is #![no_std] at its core, gating the two heap-backed implementations behind a default-on alloc feature that pulls in extern crate alloc rather than the full standard library. It has no runtime dependencies at all; the only dependency declared in Cargo.toml is criterion as a dev-dependency for the Criterion-based benchmarks in benches/bench.rs. CI is run through GitHub Actions (rust.yml for build/test, coverage.yml for coverage reporting), and the crate is published to crates.io with docs on docs.rs.

Code Quality Testing is extensive and colocated: src/lib.rs alone contains over 80 #[test] functions exercising shared trait behavior across all three implementations generically, with additional implementation-specific tests in with_const_generics.rs, with_alloc/alloc_ringbuffer.rs, and a dedicated tests/conversions.rs integration test file. The crate root enforces #![deny(warnings)], #![deny(missing_docs)], and several Clippy lints (must_use_candidate, default_trait_access, doc_markdown, semicolon_if_nothing_returned), so every public API surface carries documentation and the codebase must be warning-free to compile. Error handling favors Option-returning APIs (enqueue/dequeue return Option<T>) over panics, and unsafe code (used for pointer-based length/capacity access and iterator internals) is scoped narrowly with safety-comment justifications above each unsafe block.

What Makes It Unique Rather than committing to a single storage strategy, the crate unifies fixed heap, growable heap, and stack-only const-generic ring buffers behind one trait, so generic code can be written once and instantiated against whichever variant matches the deployment target — including fully allocator-free embedded environments via the const-generic implementation. Its negative/wraparound-aware indexing (get_signed) and documented safety contract for mutable iteration (iter_mut) go beyond what a hand-rolled circular buffer typically offers, while the zero-dependency, no_std-first design keeps it lightweight enough to embed in constrained targets.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search