forge_fmt/pp/
ring.rs

1use std::{
2    collections::VecDeque,
3    ops::{Index, IndexMut, Range},
4};
5
6#[derive(Debug)]
7pub(crate) struct RingBuffer<T> {
8    data: VecDeque<T>,
9    // Abstract index of data[0] in the infinitely sized queue.
10    offset: usize,
11}
12
13impl<T> RingBuffer<T> {
14    pub(crate) fn new() -> Self {
15        Self { data: VecDeque::new(), offset: 0 }
16    }
17
18    pub(crate) fn is_empty(&self) -> bool {
19        self.data.is_empty()
20    }
21
22    pub(crate) fn len(&self) -> usize {
23        self.data.len()
24    }
25
26    pub(crate) fn push(&mut self, value: T) -> usize {
27        let index = self.offset + self.data.len();
28        self.data.push_back(value);
29        index
30    }
31
32    pub(crate) fn clear(&mut self) {
33        self.data.clear();
34    }
35
36    pub(crate) fn index_range(&self) -> Range<usize> {
37        self.offset..self.offset + self.data.len()
38    }
39
40    #[inline]
41    #[track_caller]
42    pub(crate) fn first(&self) -> &T {
43        &self.data[0]
44    }
45
46    #[inline]
47    #[track_caller]
48    pub(crate) fn first_mut(&mut self) -> &mut T {
49        &mut self.data[0]
50    }
51
52    #[inline]
53    #[track_caller]
54    pub(crate) fn pop_first(&mut self) -> T {
55        self.offset += 1;
56        self.data.pop_front().unwrap()
57    }
58
59    #[inline]
60    #[track_caller]
61    pub(crate) fn last(&self) -> &T {
62        self.data.back().unwrap()
63    }
64
65    #[inline]
66    #[track_caller]
67    pub(crate) fn last_mut(&mut self) -> &mut T {
68        self.data.back_mut().unwrap()
69    }
70
71    #[inline]
72    #[track_caller]
73    pub(crate) fn second_last(&self) -> &T {
74        &self.data[self.data.len() - 2]
75    }
76
77    #[inline]
78    #[track_caller]
79    pub(crate) fn pop_last(&mut self) {
80        self.data.pop_back().unwrap();
81    }
82}
83
84impl<T> Index<usize> for RingBuffer<T> {
85    type Output = T;
86    fn index(&self, index: usize) -> &Self::Output {
87        &self.data[index.checked_sub(self.offset).unwrap()]
88    }
89}
90
91impl<T> IndexMut<usize> for RingBuffer<T> {
92    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
93        &mut self.data[index.checked_sub(self.offset).unwrap()]
94    }
95}