event_scanner/block_range_scanner/
ring_buffer.rs1use std::collections::VecDeque;
2
3#[derive(Copy, Clone, Debug)]
4pub enum RingBufferCapacity {
5 Limited(usize),
6 Infinite,
7}
8
9macro_rules! impl_from_unsigned {
10 ($target:ty; $($source:ty),+ $(,)?) => {
11 $(
12 impl From<$source> for $target {
13 fn from(value: $source) -> Self {
14 RingBufferCapacity::Limited(value as usize)
15 }
16 }
17 )+
18 };
19}
20
21impl_from_unsigned!(RingBufferCapacity; u8, u16, u32, usize);
22
23#[derive(Clone)]
24pub(crate) struct RingBuffer<T> {
25 inner: VecDeque<T>,
26 capacity: RingBufferCapacity,
27}
28
29impl<T> RingBuffer<T> {
30 pub fn new(capacity: RingBufferCapacity) -> Self {
32 if let RingBufferCapacity::Limited(limit) = capacity {
33 Self { inner: VecDeque::with_capacity(limit), capacity }
34 } else {
35 Self { inner: VecDeque::new(), capacity }
36 }
37 }
38
39 pub fn push(&mut self, item: T) {
43 match self.capacity {
44 RingBufferCapacity::Infinite => {
45 self.inner.push_back(item); }
47 RingBufferCapacity::Limited(0) => {
48 }
50 RingBufferCapacity::Limited(limit) => {
51 if self.inner.len() == limit {
52 self.inner.pop_front(); }
54 self.inner.push_back(item); }
56 }
57 }
58
59 pub fn pop_back(&mut self) -> Option<T> {
60 self.inner.pop_back()
61 }
62
63 pub fn back(&self) -> Option<&T> {
64 self.inner.back()
65 }
66
67 pub fn clear(&mut self) {
68 self.inner.clear();
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn zero_capacity_should_ignore_elements() {
78 let mut buf = RingBuffer::<u32>::new(RingBufferCapacity::Limited(0));
79 buf.push(1);
80 assert!(buf.inner.is_empty());
81 }
82}