1#![doc = include_str!("../README.md")]
2#![no_std]
3
4use core::ops::{Deref, DerefMut};
5use core::borrow::{Borrow, BorrowMut};
6use core::fmt::{Debug, Formatter, Pointer};
7
8pub struct DoubleBuffer<T> {
69 swapped: bool,
70 buffers: [T; 2],
71}
72
73impl<T> DoubleBuffer<T> {
74 #[inline]
75 pub const fn new(current: T, next: T) -> Self {
76 Self { swapped: false, buffers: [current, next] }
77 }
78
79 #[inline]
96 pub fn swap(&mut self) {
97 self.swapped = !self.swapped;
98 }
99
100 #[inline]
101 const fn current_offset(&self) -> usize {
102 if self.swapped {
103 return 1;
104 }
105 return 0;
106 }
107
108 #[inline]
109 const fn next_offset(&self) -> usize {
110 if self.swapped {
111 return 0;
112 }
113 return 1;
114 }
115
116 #[inline]
117 const fn current(&self) -> &T {
118 &self.buffers[self.current_offset()]
119 }
120
121 #[inline]
122 const fn next(&self) -> &T {
123 &self.buffers[self.next_offset()]
124 }
125
126 #[inline]
127 fn current_mut(&mut self) -> &mut T {
128 &mut self.buffers[self.current_offset()]
129 }
130
131 #[inline]
132 fn next_mut(&mut self) -> &mut T {
133 &mut self.buffers[self.next_offset()]
134 }
135}
136
137impl<T: Clone> DoubleBuffer<T> {
138 #[inline]
155 pub fn swap_with_clone(&mut self) {
156 let next = self.next().clone();
157 let current = self.current_mut();
158 *current = next;
159 }
160}
161
162impl<T: Default> DoubleBuffer<T> {
163 #[inline]
167 pub fn swap_with_default(&mut self) {
168 self.swap();
169 let next = self.next_mut();
170 *next = T::default();
171 }
172}
173
174impl<T: Debug> Debug for DoubleBuffer<T> {
175 #[inline]
176 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
177 f.debug_struct("DoubleBuffer")
178 .field("current", self.current())
179 .field("next", self.next())
180 .finish()
181 }
182}
183
184impl<T> Pointer for DoubleBuffer<T> {
185 #[inline]
186 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
187 write!(f, "{:p}", self.current())
188 }
189}
190
191impl<T: Default> Default for DoubleBuffer<T> {
192 #[inline]
193 fn default() -> Self {
194 Self::new(T::default(), T::default())
195 }
196}
197
198impl<T> Deref for DoubleBuffer<T> {
199 type Target = T;
200
201 #[inline]
202 fn deref(&self) -> &Self::Target {
203 self.current()
204 }
205}
206
207impl<T> DerefMut for DoubleBuffer<T> {
208 #[inline]
209 fn deref_mut(&mut self) -> &mut Self::Target {
210 self.next_mut()
211 }
212}
213
214impl<T> Borrow<T> for DoubleBuffer<T> {
215 #[inline]
216 fn borrow(&self) -> &T {
217 self.current()
218 }
219}
220
221impl<T> BorrowMut<T> for DoubleBuffer<T> {
222 #[inline]
223 fn borrow_mut(&mut self) -> &mut T {
224 self.next_mut()
225 }
226}
227
228impl<T> AsRef<T> for DoubleBuffer<T> {
229 #[inline]
230 fn as_ref(&self) -> &T {
231 self.current()
232 }
233}
234
235impl<T> AsMut<T> for DoubleBuffer<T> {
236 #[inline]
237 fn as_mut(&mut self) -> &mut T {
238 self.next_mut()
239 }
240}
241
242impl<T: PartialEq> PartialEq<T> for DoubleBuffer<T> {
243 #[inline]
244 fn eq(&self, other: &T) -> bool {
245 self.current().eq(other)
246 }
247}
248
249impl<T: PartialEq> PartialEq for DoubleBuffer<T> {
250 #[inline]
251 fn eq(&self, other: &Self) -> bool {
252 self.current().eq(other.current())
253 }
254}
255
256impl<T: Eq> Eq for DoubleBuffer<T> {}
257
258impl<T: PartialOrd> PartialOrd<T> for DoubleBuffer<T> {
259 #[inline]
260 fn partial_cmp(&self, other: &T) -> Option<core::cmp::Ordering> {
261 self.current().partial_cmp(other)
262 }
263}
264
265impl<T: PartialOrd> PartialOrd for DoubleBuffer<T> {
266 #[inline]
267 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
268 self.current().partial_cmp(other.current())
269 }
270}
271
272impl<T: Ord> Ord for DoubleBuffer<T> {
273 #[inline]
274 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
275 self.current().cmp(other.current())
276 }
277}
278
279#[cfg(test)]
280mod tests {
281 use super::*;
282
283 #[test]
284 fn test_access_and_modify_with_swap() {
285 let mut buffer: DoubleBuffer<u32> = DoubleBuffer::new(1, 2);
286 assert_eq!(buffer, 1);
287
288 *buffer = 3;
289 assert_eq!(buffer, 1);
290
291 buffer.swap();
292 assert_eq!(buffer, 3);
293 }
294
295 #[test]
296 fn test_access_and_modify_with_swap_with_clone() {
297 let mut buffer: DoubleBuffer<u32> = DoubleBuffer::new(1, 2);
298 assert_eq!(buffer, 1);
299
300 *buffer = 3;
301 assert_eq!(buffer, 1);
302
303 buffer.swap_with_clone();
304 assert_eq!(buffer, 3);
305 }
306
307 #[test]
308 fn test_access_and_modify_with_swap_with_default() {
309 let mut buffer: DoubleBuffer<u32> = DoubleBuffer::new(1, 2);
310 assert_eq!(buffer, 1);
311
312 *buffer = 3;
313 assert_eq!(buffer, 1);
314
315 buffer.swap_with_default();
316 assert_eq!(buffer, 3);
317 }
318
319 #[test]
320 fn test_swap() {
321 let mut buffer: DoubleBuffer<u32> = DoubleBuffer::new(1, 2);
322 assert_eq!(*buffer.current(), 1);
323 assert_eq!(*buffer.next(), 2);
324
325 buffer.swap();
326 assert_eq!(*buffer.current(), 2);
327 assert_eq!(*buffer.next(), 1);
328 }
329
330 #[test]
331 fn test_swap_with_clone() {
332 let mut buffer: DoubleBuffer<u32> = DoubleBuffer::new(1, 2);
333 assert_eq!(*buffer.current(), 1);
334 assert_eq!(*buffer.next(), 2);
335
336 buffer.swap_with_clone();
337 assert_eq!(*buffer.current(), 2);
338 assert_eq!(*buffer.next(), 2);
339 }
340
341 #[test]
342 fn test_swap_with_default() {
343 let mut buffer: DoubleBuffer<u32> = DoubleBuffer::new(1, 2);
344 assert_eq!(*buffer.current(), 1);
345 assert_eq!(*buffer.next(), 2);
346
347 buffer.swap_with_default();
348 assert_eq!(*buffer.current(), 2);
349 assert_eq!(*buffer.next(), 0);
350 }
351
352 #[test]
353 fn test_greater_and_less_than() {
354 let mut buffer: DoubleBuffer<i32> = DoubleBuffer::default();
355 *buffer = 1;
356 assert!(buffer > -1);
357 assert!(buffer < 1);
358
359 buffer.swap();
360 assert!(buffer > 0);
361 assert!(buffer < 2);
362 }
363
364 #[test]
365 fn test_modify_bytes_array() {
366 let mut buffer: DoubleBuffer<[u8; 3]> = DoubleBuffer::default();
367 buffer[1] = 2;
368 assert_eq!(buffer[1], 0);
369 assert_eq!(buffer, [0, 0, 0]);
370
371 assert_eq!(*buffer.current(), [0, 0, 0]);
372 assert_eq!(*buffer.next(), [0, 2, 0]);
373
374 buffer.swap();
375 assert_eq!(buffer[1], 2);
376 assert_eq!(buffer, [0, 2, 0]);
377
378 assert_eq!(*buffer.current(), [0, 2, 0]);
379 assert_eq!(*buffer.next(), [0, 0, 0]);
380 }
381
382 #[test]
383 fn test_for_iter_mut_bytes_array() {
384 let mut buffer: DoubleBuffer<[u8; 3]> = DoubleBuffer::default();
385 buffer[1] = 2;
386
387 assert_eq!(*buffer.current(), [0, 0, 0]);
388 assert_eq!(*buffer.next(), [0, 2, 0]);
389
390 for byte in buffer.iter_mut() {
391 *byte += 1;
392 }
393
394 assert_eq!(*buffer.current(), [0, 0, 0]);
395 assert_eq!(*buffer.next(), [1, 3, 1]);
396 }
397}