Line data Source code
1 : //! A heapless buffer for events of sorts.
2 :
3 : use std::ops;
4 :
5 : use heapless::HistoryBuffer;
6 :
7 7142 : #[derive(Debug, Clone)]
8 : pub struct HistoryBufferWithDropCounter<T, const L: usize> {
9 : buffer: HistoryBuffer<T, L>,
10 : drop_count: u64,
11 : }
12 :
13 : impl<T, const L: usize> HistoryBufferWithDropCounter<T, L> {
14 87689904 : pub fn write(&mut self, data: T) {
15 87689904 : let len_before = self.buffer.len();
16 87689904 : self.buffer.write(data);
17 87689904 : let len_after = self.buffer.len();
18 87689904 : self.drop_count += u64::from(len_before == len_after);
19 87689904 : }
20 12 : pub fn drop_count(&self) -> u64 {
21 12 : self.drop_count
22 12 : }
23 2276 : pub fn map<U, F: Fn(&T) -> U>(&self, f: F) -> HistoryBufferWithDropCounter<U, L> {
24 2276 : let mut buffer = HistoryBuffer::new();
25 2276 : buffer.extend(self.buffer.oldest_ordered().map(f));
26 2276 : HistoryBufferWithDropCounter::<U, L> {
27 2276 : buffer,
28 2276 : drop_count: self.drop_count,
29 2276 : }
30 2276 : }
31 : }
32 :
33 : impl<T, const L: usize> Default for HistoryBufferWithDropCounter<T, L> {
34 91844 : fn default() -> Self {
35 91844 : Self {
36 91844 : buffer: HistoryBuffer::default(),
37 91844 : drop_count: 0,
38 91844 : }
39 91844 : }
40 : }
41 :
42 : impl<T, const L: usize> ops::Deref for HistoryBufferWithDropCounter<T, L> {
43 : type Target = HistoryBuffer<T, L>;
44 :
45 1702 : fn deref(&self) -> &Self::Target {
46 1702 : &self.buffer
47 1702 : }
48 : }
49 :
50 4546 : #[derive(serde::Serialize)]
51 : struct SerdeRepr<T> {
52 : buffer: Vec<T>,
53 : drop_count: u64,
54 : }
55 :
56 : impl<'a, T, const L: usize> From<&'a HistoryBufferWithDropCounter<T, L>> for SerdeRepr<T>
57 : where
58 : T: Clone + serde::Serialize,
59 : {
60 4546 : fn from(value: &'a HistoryBufferWithDropCounter<T, L>) -> Self {
61 4546 : let HistoryBufferWithDropCounter { buffer, drop_count } = value;
62 4546 : SerdeRepr {
63 4546 : buffer: buffer.iter().cloned().collect(),
64 4546 : drop_count: *drop_count,
65 4546 : }
66 4546 : }
67 : }
68 :
69 : impl<T, const L: usize> serde::Serialize for HistoryBufferWithDropCounter<T, L>
70 : where
71 : T: Clone + serde::Serialize,
72 : {
73 4546 : fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
74 4546 : where
75 4546 : S: serde::Serializer,
76 4546 : {
77 4546 : SerdeRepr::from(self).serialize(serializer)
78 4546 : }
79 : }
80 :
81 : #[cfg(test)]
82 : mod test {
83 : use super::HistoryBufferWithDropCounter;
84 :
85 1 : #[test]
86 1 : fn test_basics() {
87 1 : let mut b = HistoryBufferWithDropCounter::<_, 2>::default();
88 1 : b.write(1);
89 1 : b.write(2);
90 1 : b.write(3);
91 2 : assert!(b.iter().any(|e| *e == 2));
92 1 : assert!(b.iter().any(|e| *e == 3));
93 2 : assert!(!b.iter().any(|e| *e == 1));
94 1 : }
95 :
96 1 : #[test]
97 1 : fn test_drop_count_works() {
98 1 : let mut b = HistoryBufferWithDropCounter::<_, 2>::default();
99 1 : b.write(1);
100 1 : assert_eq!(b.drop_count(), 0);
101 1 : b.write(2);
102 1 : assert_eq!(b.drop_count(), 0);
103 1 : b.write(3);
104 1 : assert_eq!(b.drop_count(), 1);
105 1 : b.write(4);
106 1 : assert_eq!(b.drop_count(), 2);
107 1 : }
108 :
109 1 : #[test]
110 1 : fn test_clone_works() {
111 1 : let mut b = HistoryBufferWithDropCounter::<_, 2>::default();
112 1 : b.write(1);
113 1 : b.write(2);
114 1 : b.write(3);
115 1 : assert_eq!(b.drop_count(), 1);
116 1 : let mut c = b.clone();
117 1 : assert_eq!(c.drop_count(), 1);
118 2 : assert!(c.iter().any(|e| *e == 2));
119 1 : assert!(c.iter().any(|e| *e == 3));
120 2 : assert!(!c.iter().any(|e| *e == 1));
121 :
122 1 : c.write(4);
123 2 : assert!(c.iter().any(|e| *e == 4));
124 2 : assert!(!b.iter().any(|e| *e == 4));
125 1 : }
126 :
127 1 : #[test]
128 1 : fn test_map() {
129 1 : let mut b = HistoryBufferWithDropCounter::<_, 2>::default();
130 1 :
131 1 : b.write(1);
132 1 : assert_eq!(b.drop_count(), 0);
133 : {
134 1 : let c = b.map(|i| i + 10);
135 1 : assert_eq!(c.oldest_ordered().cloned().collect::<Vec<_>>(), vec![11]);
136 1 : assert_eq!(c.drop_count(), 0);
137 : }
138 :
139 1 : b.write(2);
140 1 : assert_eq!(b.drop_count(), 0);
141 : {
142 2 : let c = b.map(|i| i + 10);
143 1 : assert_eq!(
144 1 : c.oldest_ordered().cloned().collect::<Vec<_>>(),
145 1 : vec![11, 12]
146 1 : );
147 1 : assert_eq!(c.drop_count(), 0);
148 : }
149 :
150 1 : b.write(3);
151 1 : assert_eq!(b.drop_count(), 1);
152 : {
153 2 : let c = b.map(|i| i + 10);
154 1 : assert_eq!(
155 1 : c.oldest_ordered().cloned().collect::<Vec<_>>(),
156 1 : vec![12, 13]
157 1 : );
158 1 : assert_eq!(c.drop_count(), 1);
159 : }
160 1 : }
161 : }
|