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