1use std::collections::VecDeque;
2use std::ops::{Index, IndexMut};
3
4pub struct RingBuffer<T> {
5 data: VecDeque<T>,
6 // Abstract index of data[0] in infinitely sized queue
7 offset: usize,
8}
9
10impl<T> RingBuffer<T> {
11 pub fn new() -> Self {
12 RingBuffer {
13 data: VecDeque::new(),
14 offset: 0,
15 }
16 }
17
18 pub fn is_empty(&self) -> bool {
19 self.data.is_empty()
20 }
21
22 pub fn len(&self) -> usize {
23 self.data.len()
24 }
25
26 pub 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 fn clear(&mut self) {
33 self.data.clear();
34 }
35
36 pub fn index_of_first(&self) -> usize {
37 self.offset
38 }
39
40 pub fn first(&self) -> &T {
41 &self.data[0]
42 }
43
44 pub fn first_mut(&mut self) -> &mut T {
45 &mut self.data[0]
46 }
47
48 pub fn pop_first(&mut self) -> T {
49 self.offset += 1;
50 self.data.pop_front().unwrap()
51 }
52
53 pub fn last(&self) -> &T {
54 self.data.back().unwrap()
55 }
56
57 pub fn last_mut(&mut self) -> &mut T {
58 self.data.back_mut().unwrap()
59 }
60
61 pub fn second_last(&self) -> &T {
62 &self.data[self.data.len() - 2]
63 }
64
65 pub fn pop_last(&mut self) {
66 self.data.pop_back().unwrap();
67 }
68}
69
70impl<T> Index<usize> for RingBuffer<T> {
71 type Output = T;
72 fn index(&self, index: usize) -> &Self::Output {
73 &self.data[index.checked_sub(self.offset).unwrap()]
74 }
75}
76
77impl<T> IndexMut<usize> for RingBuffer<T> {
78 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
79 &mut self.data[index.checked_sub(self.offset).unwrap()]
80 }
81}
82