grammers_crypto/
deque_buffer.rs1use std::{
10 ops::{Index, IndexMut},
11 slice::SliceIndex,
12};
13
14#[derive(Clone, Debug)]
20pub struct DequeBuffer<T: Copy + Default> {
21 buffer: Vec<T>,
22 head: usize,
23 default_head: usize,
24}
25
26impl<T: Copy + Default> DequeBuffer<T> {
27 pub fn with_capacity(back_capacity: usize, front_capacity: usize) -> Self {
30 let mut buffer = Vec::with_capacity(front_capacity + back_capacity);
31 buffer.extend((0..front_capacity).map(|_| T::default()));
32 Self {
33 buffer,
34 head: front_capacity,
35 default_head: front_capacity,
36 }
37 }
38
39 pub fn clear(&mut self) {
41 self.buffer.truncate(self.default_head);
42 self.buffer.fill(T::default());
43 self.head = self.default_head;
44 }
45
46 pub fn extend_front(&mut self, slice: &[T]) {
48 if self.head >= slice.len() {
49 self.head -= slice.len()
50 } else {
51 let shift = slice.len() - self.head;
52 self.buffer.extend((0..shift).map(|_| T::default()));
53 self.buffer.rotate_right(shift);
54 self.head = 0;
55 }
56 self.buffer[self.head..self.head + slice.len()].copy_from_slice(slice);
57 }
58
59 pub fn push(&mut self, value: T) {
61 self.buffer.push(value)
62 }
63
64 pub fn is_empty(&self) -> bool {
66 self.head == self.buffer.len()
67 }
68
69 pub fn len(&self) -> usize {
71 self.buffer.len() - self.head
72 }
73}
74
75impl<T: Copy + Default> AsRef<[T]> for DequeBuffer<T> {
76 fn as_ref(&self) -> &[T] {
77 &self.buffer[self.head..]
78 }
79}
80
81impl<T: Copy + Default> AsMut<[T]> for DequeBuffer<T> {
82 fn as_mut(&mut self) -> &mut [T] {
83 &mut self.buffer[self.head..]
84 }
85}
86
87impl<T: Copy + Default, I: SliceIndex<[T]>> Index<I> for DequeBuffer<T> {
88 type Output = I::Output;
89
90 fn index(&self, index: I) -> &Self::Output {
91 self.as_ref().index(index)
92 }
93}
94
95impl<T: Copy + Default, I: SliceIndex<[T]>> IndexMut<I> for DequeBuffer<T> {
96 fn index_mut(&mut self, index: I) -> &mut Self::Output {
97 self.as_mut().index_mut(index)
98 }
99}
100
101impl<T: Copy + Default> Extend<T> for DequeBuffer<T> {
102 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
103 self.buffer.extend(iter)
104 }
105}
106
107impl<'a, T: Copy + Default + 'a> Extend<&'a T> for DequeBuffer<T> {
108 fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
109 self.buffer.extend(iter)
110 }
111}
112
113#[cfg(test)]
114mod tests {
115 use super::*;
116
117 fn repr(ring: &DequeBuffer<u8>) -> String {
119 use std::fmt::Write as _;
120
121 let mut repr = String::new();
122 repr.push('[');
123 ring.buffer.iter().enumerate().for_each(|(i, c)| {
124 repr.push(if ring.head == i { '|' } else { ' ' });
125 write!(repr, "{c}").unwrap();
126 });
127 repr.push(if ring.head == ring.buffer.len() {
128 '|'
129 } else {
130 ' '
131 });
132 (ring.buffer.len()..ring.buffer.capacity()).for_each(|_| {
133 repr.push('?');
134 repr.push(' ');
135 });
136 repr.push(']');
137 repr
138 }
139
140 #[allow(clippy::len_zero)]
141 fn sanity_checks(ring: &DequeBuffer<u8>) {
142 assert_eq!(ring.as_ref().len(), ring.len());
143 assert_eq!(ring.is_empty(), ring.len() == 0);
144 }
145
146 #[test]
147 fn initialization() {
148 let buffer = DequeBuffer::<u8>::with_capacity(0, 0);
149 sanity_checks(&buffer);
150 assert!(buffer.is_empty());
151 assert_eq!(repr(&buffer), "[|]");
152
153 let buffer = DequeBuffer::<u8>::with_capacity(0, 4);
154 sanity_checks(&buffer);
155 assert!(buffer.is_empty());
156 assert_eq!(repr(&buffer), "[ 0 0 0 0|]");
157
158 let buffer = DequeBuffer::<u8>::with_capacity(4, 0);
159 sanity_checks(&buffer);
160 assert!(buffer.is_empty());
161 assert_eq!(repr(&buffer), "[|? ? ? ? ]");
162
163 let buffer = DequeBuffer::<u8>::with_capacity(2, 4);
164 sanity_checks(&buffer);
165 assert!(buffer.is_empty());
166 assert_eq!(repr(&buffer), "[ 0 0 0 0|? ? ]");
167 }
168
169 #[test]
170 fn shift_extends_if_needed() {
171 let mut buffer = DequeBuffer::<u8>::with_capacity(2, 4);
172
173 buffer.extend_front(&[3, 3, 3]);
174 sanity_checks(&buffer);
175 assert_eq!(repr(&buffer), "[ 0|3 3 3 ? ? ]");
176
177 buffer.extend_front(&[1]);
178 sanity_checks(&buffer);
179 assert_eq!(repr(&buffer), "[|1 3 3 3 ? ? ]");
180
181 buffer.extend_front(&[2, 2]);
182 sanity_checks(&buffer);
183 assert_eq!(repr(&buffer), "[|2 2 1 3 3 3 ]");
184
185 let mut buffer = DequeBuffer::<u8>::with_capacity(2, 4);
186
187 buffer.extend_front(&[5, 5, 5, 5, 5]);
188 sanity_checks(&buffer);
189 assert_eq!(repr(&buffer), "[|5 5 5 5 5 ? ]");
190
191 buffer.extend_front(&[2, 2]);
192 sanity_checks(&buffer);
193 assert!(repr(&buffer).starts_with("[|2 2 5 5 5 5 5 ?")); }
195
196 #[test]
197 fn mutates_as_expected() {
198 let mut buffer = DequeBuffer::<u8>::with_capacity(6, 4);
199
200 buffer.extend(1..=2);
201 sanity_checks(&buffer);
202 assert_eq!(repr(&buffer), "[ 0 0 0 0|1 2 ? ? ? ? ]");
203
204 buffer.push(3);
205 sanity_checks(&buffer);
206 assert_eq!(repr(&buffer), "[ 0 0 0 0|1 2 3 ? ? ? ]");
207
208 buffer.extend_front(&[4, 5, 6]);
209 sanity_checks(&buffer);
210 assert_eq!(repr(&buffer), "[ 0|4 5 6 1 2 3 ? ? ? ]");
211
212 buffer.clear();
213 assert_eq!(repr(&buffer), "[ 0 0 0 0|? ? ? ? ? ? ]");
214 }
215}