1pub trait SizeTracker: Clone {
7 const INIT: Self;
9 const IS_TRACKING: bool;
11 fn increment(&mut self);
13 fn decrement(&mut self);
15 fn get(&self) -> usize;
17 fn set(&mut self, size: usize);
19 fn swap(&mut self, other: &mut Self);
21}
22
23#[derive(Clone, Copy)]
25pub struct NonTrackingSize;
26impl SizeTracker for NonTrackingSize {
27 const INIT: Self = NonTrackingSize;
28 const IS_TRACKING: bool = false;
29 #[inline]
30 fn increment(&mut self) {}
31 #[inline]
32 fn decrement(&mut self) {}
33 #[inline]
34 fn get(&self) -> usize {
35 panic!("Cannot get the size if we are not tracking the size.")
36 }
37 #[inline]
38 fn set(&mut self, _size: usize) {}
39 #[inline]
40 fn swap(&mut self, _other: &mut Self) {}
41}
42
43#[derive(Clone, Copy)]
45pub struct TrackingSize(usize);
46impl SizeTracker for TrackingSize {
47 const INIT: Self = TrackingSize(0);
48 const IS_TRACKING: bool = true;
49 #[inline]
50 fn increment(&mut self) {
51 self.0 += 1;
52 }
53 #[inline]
54 fn decrement(&mut self) {
55 self.0 -= 1;
56 }
57 #[inline]
58 fn get(&self) -> usize {
59 self.0
60 }
61 #[inline]
62 fn set(&mut self, size: usize) {
63 self.0 = size;
64 }
65 #[inline]
66 fn swap(&mut self, other: &mut Self) {
67 core::mem::swap(&mut self.0, &mut other.0);
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 #[should_panic(expected = "Cannot get the size if we are not tracking the size.")]
77 fn test_non_tracking_size_get_panics() {
78 let tracker = NonTrackingSize;
79 let _ = tracker.get();
80 }
81
82 #[test]
83 fn test_non_tracking_size_set_swap() {
84 let mut tracker1 = NonTrackingSize;
85 let mut tracker2 = NonTrackingSize;
86 tracker1.increment();
87 tracker1.decrement();
88 tracker1.set(10);
89 tracker1.swap(&mut tracker2);
90 assert!(!NonTrackingSize::IS_TRACKING);
91 }
92
93 #[test]
94 fn test_tracking_size_increment_decrement() {
95 let mut tracker = TrackingSize::INIT;
96 assert!(TrackingSize::IS_TRACKING);
97 assert_eq!(tracker.get(), 0);
98 tracker.increment();
99 assert_eq!(tracker.get(), 1);
100 tracker.increment();
101 assert_eq!(tracker.get(), 2);
102 tracker.decrement();
103 assert_eq!(tracker.get(), 1);
104 }
105
106 #[test]
107 fn test_tracking_size_set() {
108 let mut tracker = TrackingSize::INIT;
109 tracker.set(100);
110 assert_eq!(tracker.get(), 100);
111 }
112
113 #[test]
114 fn test_tracking_size_swap() {
115 let mut tracker1 = TrackingSize::INIT;
116 tracker1.set(100);
117 let mut tracker2 = TrackingSize::INIT;
118 tracker2.set(50);
119
120 tracker1.swap(&mut tracker2);
121 assert_eq!(tracker1.get(), 50);
122 assert_eq!(tracker2.get(), 100);
123 }
124}