1use core::fmt::Debug;
2
3#[cfg(feature = "std")]
5#[derive(Debug, Clone, Eq)]
6pub struct DistinctReports(Vec<[u8; 8]>);
7
8#[cfg(feature = "std")]
9impl Default for DistinctReports {
10 fn default() -> Self {
11 Self::new()
12 }
13}
14
15#[cfg(feature = "std")]
16impl core::cmp::PartialEq for DistinctReports {
17 fn eq(&self, other: &Self) -> bool {
18 if self.0[0] != other.0[0] {
20 return false;
21 }
22
23 let mut i: usize = 1;
24 let mut j: usize = 1;
25
26 let self_len = self.0.len();
27 let other_len = other.0.len();
28
29 while i < self_len && j < other_len {
31 while (i < self_len - 1) && self.0[i] == [0; 8] {
34 i += 1;
35 }
36 while (j < other_len - 1) && other.0[j] == [0; 8] {
37 j += 1;
38 }
39
40 if self.0[i] != other.0[j] {
41 if i > 0
45 && i < self_len - 1
46 && self.0[i + 1] == other.0[j]
47 && ((self.0[i - 1][0] == self.0[i][0] && self.0[i][2..] == self.0[i + 1][2..])
48 || (self.0[i - 1][2..] == self.0[i][2..]
49 && self.0[i][0] == self.0[i + 1][0]))
50 {
51 i += 1;
53 } else if j > 0
54 && j < other_len - 1
55 && self.0[i] == other.0[j + 1]
56 && ((other.0[j - 1][0] == other.0[j][0]
57 && other.0[j][2..] == other.0[j + 1][2..])
58 || (other.0[j - 1][2..] == other.0[j][2..]
59 && other.0[j][0] == other.0[j + 1][0]))
60 {
61 j += 1;
63 } else {
64 return false;
65 }
66 }
67
68 i += 1;
69 j += 1;
70 }
71
72 i == self_len && j == other_len
73 }
74}
75
76#[cfg(feature = "std")]
77impl DistinctReports {
78 pub fn new() -> Self {
80 Self(vec![[0; 8]])
81 }
82
83 pub fn update(&mut self, report: [u8; 8]) {
85 match self.0.last() {
86 Some(last_report) if last_report == &report => {}
87 _ => self.0.push(report),
88 }
89 }
90
91 pub fn reports(&self) -> &[[u8; 8]] {
93 self.0.as_slice()
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100
101 #[test]
102 fn test_distinct_reports_equal() {
103 let lhs = DistinctReports(vec![[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0x04, 0, 0, 0, 0, 0]]);
105 let rhs = DistinctReports(vec![[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0x04, 0, 0, 0, 0, 0]]);
106
107 assert!(lhs == rhs);
111 }
112
113 #[test]
114 fn test_distinct_reports_not_equal() {
115 let lhs = DistinctReports(vec![[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0x04, 0, 0, 0, 0, 0]]);
117 let rhs = DistinctReports(vec![[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0x05, 0, 0, 0, 0, 0]]);
118
119 assert!(lhs != rhs);
123 }
124
125 #[test]
126 fn test_distinct_reports_not_equal_modif() {
127 let lhs = DistinctReports(vec![[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0x04, 0, 0, 0, 0, 0]]);
129 let rhs = DistinctReports(vec![
130 [0, 0, 0, 0, 0, 0, 0, 0],
131 [0x01, 0, 0x04, 0, 0, 0, 0, 0],
132 ]);
133
134 assert!(lhs != rhs);
138 }
139
140 #[test]
141 fn test_distinct_reports_equal_ignores_0_between() {
142 let lhs = DistinctReports(vec![
144 [0, 0, 0, 0, 0, 0, 0, 0],
145 [0, 0, 0x04, 0, 0, 0, 0, 0],
146 [0, 0, 0x05, 0, 0, 0, 0, 0],
147 ]);
148 let rhs = DistinctReports(vec![
149 [0, 0, 0, 0, 0, 0, 0, 0],
150 [0, 0, 0x04, 0, 0, 0, 0, 0],
151 [0, 0, 0, 0, 0, 0, 0, 0],
152 [0, 0, 0x05, 0, 0, 0, 0, 0],
153 ]);
154
155 assert!(lhs == rhs);
159 }
160
161 #[test]
162 fn test_distinct_reports_not_equal_respects_trailing_0() {
163 let lhs = DistinctReports(vec![
165 [0, 0, 0, 0, 0, 0, 0, 0],
166 [0, 0, 0x04, 0, 0, 0, 0, 0],
167 [0, 0, 0x05, 0, 0, 0, 0, 0],
168 [0, 0, 0, 0, 0, 0, 0, 0],
169 ]);
170 let rhs = DistinctReports(vec![
171 [0, 0, 0, 0, 0, 0, 0, 0],
172 [0, 0, 0x04, 0, 0, 0, 0, 0],
173 [0, 0, 0, 0, 0, 0, 0, 0],
174 [0, 0, 0x05, 0, 0, 0, 0, 0],
175 ]);
176
177 assert!(lhs != rhs);
181 }
182
183 #[test]
184 fn test_distinct_reports_update_ignores_consecutive_duplicate() {
185 let lhs = DistinctReports(vec![[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0x04, 0, 0, 0, 0, 0]]);
187
188 let mut rhs = DistinctReports::new();
190 rhs.update([0, 0, 0x04, 0, 0, 0, 0, 0]);
191 rhs.update([0, 0, 0x04, 0, 0, 0, 0, 0]);
192 rhs.update([0, 0, 0x04, 0, 0, 0, 0, 0]);
193
194 assert!(lhs == rhs);
196 }
197
198 #[test]
199 fn test_distinct_reports_allows_modifier_press_equivalence() {
200 let lhs = DistinctReports(vec![
202 [0, 0, 0, 0, 0, 0, 0, 0],
203 [0x01, 0, 0x04, 0, 0, 0, 0, 0],
204 ]);
205 let rhs = DistinctReports(vec![
206 [0, 0, 0, 0, 0, 0, 0, 0],
207 [0x01, 0, 0, 0, 0, 0, 0, 0],
208 [0x01, 0, 0x04, 0, 0, 0, 0, 0],
209 ]);
210
211 assert!(lhs == rhs);
215 }
216
217 #[test]
218 fn test_distinct_reports_allows_modifier_release_equivalence() {
219 let lhs = DistinctReports(vec![
221 [0, 0, 0, 0, 0, 0, 0, 0],
222 [0x01, 0, 0x04, 0, 0, 0, 0, 0],
223 [0, 0, 0, 0, 0, 0, 0, 0],
224 ]);
225 let rhs = DistinctReports(vec![
226 [0, 0, 0, 0, 0, 0, 0, 0],
227 [0x01, 0, 0, 0, 0, 0, 0, 0],
228 [0x01, 0, 0x04, 0, 0, 0, 0, 0],
229 [0x01, 0, 0, 0, 0, 0, 0, 0],
230 [0, 0, 0, 0, 0, 0, 0, 0],
231 ]);
232
233 assert!(lhs == rhs);
237 }
238}