negicon_protocol/
ringbuf.rs1pub 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 }
12
13impl<T: core::marker::Copy, const SIZE: usize> RingBuffer<T, SIZE> {
14 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 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 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 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}