pub struct RingBuffer<T, const SIZE: usize> {
buffer: [Option<T>; SIZE],
head: usize,
tail: usize,
size: usize,
}
pub enum BufferError {
Overflow,
}
impl<T: core::marker::Copy, const SIZE: usize> RingBuffer<T, SIZE> {
pub fn new() -> RingBuffer<T, SIZE> {
RingBuffer {
buffer: [None; SIZE],
head: 0,
tail: 0,
size: 0,
}
}
pub fn push(&mut self, item: T) -> Result<(), BufferError> {
let mut result: Result<(), BufferError> = Ok(());
while self.size >= SIZE {
self.discard();
result = Err(BufferError::Overflow);
}
self.buffer[self.tail] = Some(item);
self.tail = (self.tail + 1) % SIZE;
self.size += 1;
result
}
pub fn peek(&mut self) -> Option<&mut T> {
if self.size > 0 {
self.buffer[self.head].as_mut()
} else {
None
}
}
pub fn pop(&mut self) -> Option<T> {
if self.size > 0 {
let item = self.buffer[self.head].take();
self.head = (self.head + 1) % SIZE;
self.size -= 1;
item
} else {
None
}
}
pub fn discard(&mut self) {
if self.size > 0 {
self.buffer[self.head].take();
self.head = (self.head + 1) % SIZE;
self.size -= 1;
}
}
}