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