negicon_protocol/
ringbuf.rs

1pub struct RingBuffer<T, const SIZE: usize> {
2    buffer: [Option<T>; SIZE],
3    head: usize,
4    tail: usize,
5    size: usize,
6}
7
8pub enum BufferError {
9    Overflow,
10    // Other error types can be added here if needed in the future
11}
12
13impl<T: core::marker::Copy, const SIZE: usize> RingBuffer<T, SIZE> {
14    // Creates a new RingBuffer
15    pub fn new() -> RingBuffer<T, SIZE> {
16        RingBuffer {
17            buffer: [None; SIZE],
18            head: 0,
19            tail: 0,
20            size: 0,
21        }
22    }
23
24    // Adds an item to the buffer. Returns an error if the buffer is full.
25    pub fn push(&mut self, item: T) -> Result<(), BufferError> {
26        let mut result: Result<(), BufferError> = Ok(());
27        while self.size >= SIZE {
28            self.discard();
29            result = Err(BufferError::Overflow);
30        }
31        self.buffer[self.tail] = Some(item);
32        self.tail = (self.tail + 1) % SIZE;
33        self.size += 1;
34        result
35    }
36
37    // Peeks the next item in the buffer
38    pub fn peek(&mut self) -> Option<&mut T> {
39        if self.size > 0 {
40            self.buffer[self.head].as_mut()
41        } else {
42            None
43        }
44    }
45
46    pub fn pop(&mut self) -> Option<T> {
47        if self.size > 0 {
48            let item = self.buffer[self.head].take();
49            self.head = (self.head + 1) % SIZE;
50            self.size -= 1;
51            item
52        } else {
53            None
54        }
55    }
56
57    // Discards the last item in the buffer
58    pub fn discard(&mut self) {
59        if self.size > 0 {
60            self.buffer[self.head].take();
61            self.head = (self.head + 1) % SIZE;
62            self.size -= 1;
63        }
64    }
65}