0 day streak
rust / expert
Snippet

Implementing a Fixed-Size Circular Queue with Const Generics

This snippet implements a fixed-size ring buffer using Rust's const generics and array types. By asserting the Default trait on the array [Option<T>; N], the buffer can initialize its storage safely without requiring T to be Copy, utilizing atomic-like index wrapping arithmetic.

snippet.rs
rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
pub struct ArrayBuffer<T, const N: usize> {
data: [Option<T>; N],
head: usize,
tail: usize,
}
impl<T, const N: usize> ArrayBuffer<T, N> {
pub fn new() -> Self
where
[Option<T>; N]: Default,
{
Self {
data: Default::default(),
head: 0,
tail: 0,
}
}
pub fn push(&mut self, item: T) -> Result<(), &'static str> {
let next_head = (self.head + 1) % N;
if next_head == self.tail {
return Err("Queue full");
}
self.data[self.head] = Some(item);
self.head = next_head;
Ok(())
}
}
Breakdown
1
pub struct ArrayBuffer<T, const N: usize>
Declares a generic struct parameterized by both a type T and a const array size N.
2
where [Option<T>; N]: Default
Enforces that the array structure itself can be initialized with default values (which are None).
3
let next_head = (self.head + 1) % N;
Calculates the next write position using modulo arithmetic based on the array size N.
4
self.data[self.head] = Some(item);
Inserts the element into the array slot, taking advantage of standard array indexing.