event_scanner/block_range_scanner/
ring_buffer.rs1use std::collections::VecDeque;
2
3#[derive(Copy, Clone, Debug)]
7pub enum RingBufferCapacity {
8 Limited(usize),
13 Infinite,
18}
19
20macro_rules! impl_from_unsigned {
21 ($target:ty; $($source:ty),+ $(,)?) => {
22 $(
23 impl From<$source> for $target {
24 fn from(value: $source) -> Self {
25 RingBufferCapacity::Limited(value as usize)
26 }
27 }
28 )+
29 };
30}
31
32impl_from_unsigned!(RingBufferCapacity; u8, u16, u32, usize);
33
34#[derive(Clone, Debug)]
35pub(crate) struct RingBuffer<T> {
36 inner: VecDeque<T>,
37 capacity: RingBufferCapacity,
38}
39
40impl<T> RingBuffer<T> {
41 pub fn new(capacity: RingBufferCapacity) -> Self {
43 if let RingBufferCapacity::Limited(limit) = capacity {
44 Self { inner: VecDeque::with_capacity(limit), capacity }
45 } else {
46 Self { inner: VecDeque::new(), capacity }
47 }
48 }
49
50 pub fn push(&mut self, item: T) {
54 match self.capacity {
55 RingBufferCapacity::Infinite => {
56 self.inner.push_back(item); }
58 RingBufferCapacity::Limited(0) => {
59 }
61 RingBufferCapacity::Limited(limit) => {
62 if self.inner.len() == limit {
63 self.inner.pop_front(); }
65 self.inner.push_back(item); }
67 }
68 }
69
70 pub fn pop_back(&mut self) -> Option<T> {
72 self.inner.pop_back()
73 }
74
75 pub fn back(&self) -> Option<&T> {
77 self.inner.back()
78 }
79
80 pub fn clear(&mut self) {
82 self.inner.clear();
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89
90 #[test]
91 fn zero_capacity_should_ignore_elements() {
92 let mut buf = RingBuffer::<u32>::new(RingBufferCapacity::Limited(0));
93 buf.push(1);
94 assert!(buf.inner.is_empty());
95 }
96}