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