1use crate::{MAX_SIGNALS_PER_MESSAGE, Signal, compat::Vec};
2
3#[derive(Debug, Clone, PartialEq, Eq, Hash)]
7pub struct Signals {
8 signals: Vec<Signal, { MAX_SIGNALS_PER_MESSAGE }>,
9}
10
11impl From<&[Signal]> for Signals {
12 fn from(signals: &[Signal]) -> Self {
13 Self::from_slice(signals)
14 }
15}
16
17#[cfg(feature = "std")]
18impl From<std::vec::Vec<Signal>> for Signals {
19 fn from(signals: std::vec::Vec<Signal>) -> Self {
20 Self::from_slice(&signals)
21 }
22}
23
24impl From<Vec<Signal, { MAX_SIGNALS_PER_MESSAGE }>> for Signals {
25 fn from(signals: Vec<Signal, { MAX_SIGNALS_PER_MESSAGE }>) -> Self {
26 Self::from_slice(signals.as_slice())
27 }
28}
29
30impl Signals {
31 pub(crate) fn from_slice(signals: &[Signal]) -> Self {
33 let count = signals.len().min(MAX_SIGNALS_PER_MESSAGE);
34 let signals_vec: Vec<Signal, { MAX_SIGNALS_PER_MESSAGE }> =
35 signals.iter().take(count).cloned().collect();
36 Self {
37 signals: signals_vec,
38 }
39 }
40
41 #[inline]
56 #[must_use = "iterator is lazy and does nothing unless consumed"]
57 pub fn iter(&self) -> impl Iterator<Item = &Signal> + '_ {
58 self.signals.iter()
59 }
60
61 #[inline]
74 #[must_use = "return value should be used"]
75 pub fn len(&self) -> usize {
76 self.signals.len()
77 }
78
79 #[inline]
92 #[must_use = "return value should be used"]
93 pub fn is_empty(&self) -> bool {
94 self.len() == 0
95 }
96
97 #[inline]
112 #[must_use = "return value should be used"]
113 pub fn at(&self, index: usize) -> Option<&Signal> {
114 self.signals.get(index)
115 }
116
117 #[must_use = "return value should be used"]
133 pub fn find(&self, name: &str) -> Option<&Signal> {
134 self.iter().find(|s| s.name() == name)
135 }
136
137 #[must_use = "return value should be used"]
140 pub(crate) fn find_mut(&mut self, name: &str) -> Option<&mut Signal> {
141 self.signals.iter_mut().find(|s| s.name() == name)
142 }
143}
144
145#[cfg(test)]
146mod tests {
147 use super::Signals;
148 use crate::{Parser, Signal};
149
150 #[cfg(feature = "std")]
152 mod test_from_slice {
153 use super::*;
154
155 #[test]
156 fn test_signals_from_slice() {
157 let signal1 = Signal::parse(
158 &mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap(),
159 )
160 .unwrap();
161 let signal2 = Signal::parse(
162 &mut Parser::new(b"SG_ Signal2 : 8|8@0+ (1,0) [0|255] \"\"").unwrap(),
163 )
164 .unwrap();
165
166 let signals = Signals::from_slice(&[signal1, signal2]);
167 assert_eq!(signals.len(), 2);
168 assert!(!signals.is_empty());
169 assert_eq!(signals.at(0).unwrap().name(), "Signal1");
170 assert_eq!(signals.at(1).unwrap().name(), "Signal2");
171 }
172
173 #[test]
174 fn test_signals_from_signals_slice_empty() {
175 let signals = Signals::from_slice(&[]);
176 assert_eq!(signals.len(), 0);
177 assert!(signals.is_empty());
178 assert!(signals.at(0).is_none());
179 }
180
181 #[test]
182 fn test_signals_from_slice_multiple() {
183 let signal1 = Signal::parse(
185 &mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap(),
186 )
187 .unwrap();
188 let signal2 = Signal::parse(
189 &mut Parser::new(b"SG_ Signal2 : 8|8@0+ (1,0) [0|255] \"\"").unwrap(),
190 )
191 .unwrap();
192 let signal3 = Signal::parse(
193 &mut Parser::new(b"SG_ Signal3 : 16|8@0+ (1,0) [0|255] \"\"").unwrap(),
194 )
195 .unwrap();
196
197 let signals = Signals::from_slice(&[signal1, signal2, signal3]);
198 assert_eq!(signals.len(), 3);
199 assert_eq!(signals.at(0).unwrap().name(), "Signal1");
200 assert_eq!(signals.at(1).unwrap().name(), "Signal2");
201 assert_eq!(signals.at(2).unwrap().name(), "Signal3");
202 }
203 }
204
205 mod test_iter {
207 use super::*;
208
209 #[test]
210 fn test_signals_iter() {
211 let signal1 = Signal::parse(
212 &mut Parser::new(b"SG_ RPM : 0|16@0+ (0.25,0) [0|8000] \"rpm\"").unwrap(),
213 )
214 .unwrap();
215 let signal2 = Signal::parse(
216 &mut Parser::new(b"SG_ Temp : 16|8@0- (1,-40) [-40|215] \"\xC2\xB0C\"").unwrap(),
217 )
218 .unwrap();
219
220 let signals = Signals::from_slice(&[signal1, signal2]);
221 let mut iter = signals.iter();
222 assert_eq!(iter.next().unwrap().name(), "RPM");
223 assert_eq!(iter.next().unwrap().name(), "Temp");
224 assert!(iter.next().is_none());
225 }
226
227 #[test]
228 fn test_signals_iter_empty() {
229 let signals = Signals::from_slice(&[]);
230 let mut iter = signals.iter();
231 assert!(iter.next().is_none());
232 }
233
234 #[test]
235 fn test_signals_iter_multiple() {
236 let signal1 = Signal::parse(
237 &mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap(),
238 )
239 .unwrap();
240 let signal2 = Signal::parse(
241 &mut Parser::new(b"SG_ Signal2 : 8|8@0+ (1,0) [0|255] \"\"").unwrap(),
242 )
243 .unwrap();
244 let signal3 = Signal::parse(
245 &mut Parser::new(b"SG_ Signal3 : 16|8@0+ (1,0) [0|255] \"\"").unwrap(),
246 )
247 .unwrap();
248
249 let signals = Signals::from_slice(&[signal1, signal2, signal3]);
250 let mut iter = signals.iter();
251 assert_eq!(iter.next().unwrap().name(), "Signal1");
252 assert_eq!(iter.next().unwrap().name(), "Signal2");
253 assert_eq!(iter.next().unwrap().name(), "Signal3");
254 assert!(iter.next().is_none());
255 }
256 }
257
258 mod test_len {
260 use super::*;
261
262 #[test]
263 fn test_signals_len() {
264 let signals = Signals::from_slice(&[]);
265 assert_eq!(signals.len(), 0);
266
267 let signal1 = Signal::parse(
268 &mut Parser::new(b"SG_ RPM : 0|16@0+ (0.25,0) [0|8000] \"rpm\"").unwrap(),
269 )
270 .unwrap();
271 let signals = Signals::from_slice(&[signal1]);
272 assert_eq!(signals.len(), 1);
273 }
274 }
275
276 mod test_is_empty {
278 use super::*;
279
280 #[test]
281 fn test_signals_is_empty() {
282 let signals = Signals::from_slice(&[]);
283 assert!(signals.is_empty());
284 assert_eq!(signals.len(), 0);
285
286 let signal1 = Signal::parse(
287 &mut Parser::new(b"SG_ RPM : 0|16@0+ (0.25,0) [0|8000] \"rpm\"").unwrap(),
288 )
289 .unwrap();
290 let signals = Signals::from_slice(&[signal1]);
291 assert!(!signals.is_empty());
292 }
293 }
294
295 mod test_at {
297 use super::*;
298
299 #[test]
300 fn test_signals_at() {
301 let signal1 = Signal::parse(
302 &mut Parser::new(b"SG_ RPM : 0|16@0+ (0.25,0) [0|8000] \"rpm\"").unwrap(),
303 )
304 .unwrap();
305 let signal2 = Signal::parse(
306 &mut Parser::new(b"SG_ Temp : 16|8@0- (1,-40) [-40|215] \"\xC2\xB0C\"").unwrap(),
307 )
308 .unwrap();
309
310 let signals = Signals::from_slice(&[signal1, signal2]);
311 assert_eq!(signals.at(0).unwrap().name(), "RPM");
312 assert_eq!(signals.at(1).unwrap().name(), "Temp");
313 assert!(signals.at(2).is_none());
314 }
315
316 #[test]
317 fn test_signals_at_out_of_bounds() {
318 let signal = Signal::parse(
319 &mut Parser::new(b"SG_ RPM : 0|16@0+ (0.25,0) [0|8000] \"rpm\"").unwrap(),
320 )
321 .unwrap();
322
323 let signals = Signals::from_slice(&[signal]);
324
325 assert!(signals.at(0).is_some());
327 assert_eq!(signals.at(0).unwrap().name(), "RPM");
328
329 assert!(signals.at(1).is_none());
331 assert!(signals.at(100).is_none());
332 assert!(signals.at(usize::MAX).is_none());
333 }
334 }
335
336 mod test_find {
338 use super::*;
339
340 #[test]
341 fn test_signals_find() {
342 let signal1 = Signal::parse(
343 &mut Parser::new(b"SG_ RPM : 0|16@0+ (0.25,0) [0|8000] \"rpm\"").unwrap(),
344 )
345 .unwrap();
346 let signal2 = Signal::parse(
347 &mut Parser::new(b"SG_ Temp : 16|8@0- (1,-40) [-40|215] \"\xC2\xB0C\"").unwrap(),
348 )
349 .unwrap();
350
351 let signals = Signals::from_slice(&[signal1, signal2]);
352 assert_eq!(signals.find("RPM").unwrap().name(), "RPM");
353 assert_eq!(signals.find("Temp").unwrap().name(), "Temp");
354 assert!(signals.find("Nonexistent").is_none());
355 }
356
357 #[test]
358 fn test_signals_find_case_sensitive() {
359 let signal1 = Signal::parse(
360 &mut Parser::new(b"SG_ RPM : 0|16@0+ (0.25,0) [0|8000] \"rpm\"").unwrap(),
361 )
362 .unwrap();
363 let signal2 = Signal::parse(
364 &mut Parser::new(b"SG_ Temp : 16|8@0- (1,-40) [-40|215] \"\xC2\xB0C\"").unwrap(),
365 )
366 .unwrap();
367
368 let signals = Signals::from_slice(&[signal1, signal2]);
369
370 assert!(signals.find("RPM").is_some());
372 assert_eq!(signals.find("RPM").unwrap().name(), "RPM");
373
374 assert!(signals.find("rpm").is_none());
376 assert!(signals.find("Rpm").is_none());
377
378 assert!(signals.find("Temp").is_some());
380 assert_eq!(signals.find("Temp").unwrap().name(), "Temp");
381
382 assert!(signals.find("Nonexistent").is_none());
384 assert!(signals.find("").is_none());
385 }
386
387 #[test]
388 fn test_signals_find_empty_collection() {
389 let signals = Signals::from_slice(&[]);
390 assert!(signals.find("RPM").is_none());
391 assert!(signals.find("").is_none());
392 }
393
394 #[test]
395 fn test_signals_find_not_found() {
396 let signal1 = Signal::parse(
397 &mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap(),
398 )
399 .unwrap();
400
401 let signals = Signals::from_slice(&[signal1]);
402 assert!(signals.find("Nonexistent").is_none());
403 assert!(signals.find("").is_none());
404 assert!(signals.find("signal1").is_none()); }
406
407 #[test]
408 fn test_signals_find_first_match() {
409 let signal1 = Signal::parse(
410 &mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap(),
411 )
412 .unwrap();
413 let signal2 = Signal::parse(
414 &mut Parser::new(b"SG_ Signal1 : 8|8@0+ (1,0) [0|255] \"\"").unwrap(),
415 )
416 .unwrap(); let signals = Signals::from_slice(&[signal1, signal2]);
419 let found = signals.find("Signal1");
421 assert!(found.is_some());
422 assert_eq!(found.unwrap().start_bit(), 0); }
424 }
425}