1use crate::Signal;
2
3struct SignalsIter<'a, 'b> {
5 signals: &'b [Option<Signal<'a>>],
6 count: usize,
7 pos: usize,
8}
9
10impl<'a, 'b> Iterator for SignalsIter<'a, 'b> {
11 type Item = &'b Signal<'a>;
12
13 #[inline]
14 fn next(&mut self) -> Option<Self::Item> {
15 while self.pos < self.count {
16 let result = self.signals[self.pos].as_ref();
17 self.pos += 1;
18 if let Some(sig) = result {
19 return Some(sig);
20 }
21 }
22 None
23 }
24}
25
26include!(concat!(env!("OUT_DIR"), "/limits.rs"));
37
38#[derive(Debug, Clone, PartialEq, Eq, Hash)]
44pub struct Signals<'a> {
45 #[cfg(not(any(feature = "alloc", feature = "kernel")))]
46 signals: [Option<Signal<'a>>; MAX_SIGNALS_PER_MESSAGE],
47 #[cfg(any(feature = "alloc", feature = "kernel"))]
48 signals: alloc::boxed::Box<[Option<Signal<'a>>]>,
49 signal_count: usize,
50}
51
52impl<'a> Signals<'a> {
53 #[cfg(any(feature = "alloc", feature = "kernel"))]
55 pub(crate) fn from_signals_slice(signals: &[Signal<'a>]) -> Self {
56 let count = signals.len().min(MAX_SIGNALS_PER_MESSAGE);
57
58 #[cfg(not(any(feature = "alloc", feature = "kernel")))]
59 {
60 let mut signals_array: [Option<Signal<'a>>; MAX_SIGNALS_PER_MESSAGE] =
61 [const { None }; MAX_SIGNALS_PER_MESSAGE];
62 for (i, signal) in signals.iter().take(MAX_SIGNALS_PER_MESSAGE).enumerate() {
63 signals_array[i] = Some(signal.clone());
64 }
65 Self {
66 signals: signals_array,
67 signal_count: count,
68 }
69 }
70
71 #[cfg(any(feature = "alloc", feature = "kernel"))]
72 {
73 use alloc::vec::Vec;
74 let signals_vec: Vec<Option<Signal<'a>>> =
75 signals.iter().take(count).map(|signal| Some(signal.clone())).collect();
76 Self {
77 signals: signals_vec.into_boxed_slice(),
78 signal_count: count,
79 }
80 }
81 }
82
83 pub(crate) fn from_options_slice(signals: &[Option<Signal<'a>>], signal_count: usize) -> Self {
85 let count = signal_count.min(MAX_SIGNALS_PER_MESSAGE).min(signals.len());
86
87 #[cfg(not(any(feature = "alloc", feature = "kernel")))]
88 {
89 let mut signals_array: [Option<Signal<'a>>; MAX_SIGNALS_PER_MESSAGE] =
90 [const { None }; MAX_SIGNALS_PER_MESSAGE];
91 for (i, signal_opt) in signals.iter().take(count).enumerate() {
92 signals_array[i] = signal_opt.clone();
93 }
94 Self {
95 signals: signals_array,
96 signal_count: count,
97 }
98 }
99
100 #[cfg(any(feature = "alloc", feature = "kernel"))]
101 {
102 use alloc::vec::Vec;
103 let signals_vec: Vec<Option<Signal<'a>>> =
104 signals.iter().take(count).cloned().collect();
105 Self {
106 signals: signals_vec.into_boxed_slice(),
107 signal_count: count,
108 }
109 }
110 }
111
112 #[inline]
127 #[must_use = "iterator is lazy and does nothing unless consumed"]
128 pub fn iter(&self) -> impl Iterator<Item = &Signal<'a>> + '_ {
129 let signals_slice: &[Option<Signal<'a>>] = &self.signals;
130 SignalsIter {
131 signals: signals_slice,
132 count: self.signal_count,
133 pos: 0,
134 }
135 }
136
137 #[inline]
150 #[must_use]
151 pub fn len(&self) -> usize {
152 self.signal_count
153 }
154
155 #[inline]
168 #[must_use]
169 pub fn is_empty(&self) -> bool {
170 self.len() == 0
171 }
172
173 #[inline]
188 #[must_use]
189 pub fn at(&self, index: usize) -> Option<&Signal<'a>> {
190 if index >= self.signal_count {
191 return None;
192 }
193 self.signals[index].as_ref()
194 }
195
196 #[must_use]
212 pub fn find(&self, name: &str) -> Option<&Signal<'a>> {
213 self.iter().find(|s| s.name() == name)
214 }
215
216 pub(crate) const fn max_capacity() -> usize {
218 MAX_SIGNALS_PER_MESSAGE
219 }
220
221 #[cfg(not(any(feature = "alloc", feature = "kernel")))]
224 pub(crate) fn new_parse_buffer<'b>() -> [Option<Signal<'b>>; MAX_SIGNALS_PER_MESSAGE] {
225 [const { None }; MAX_SIGNALS_PER_MESSAGE]
226 }
227}
228
229#[cfg(test)]
230mod tests {
231 use super::Signals;
232 use crate::{Parser, Signal};
233
234 #[cfg(any(feature = "alloc", feature = "kernel"))]
236 mod tests_with_alloc {
237 use super::*;
238
239 #[test]
240 fn test_signals_from_signals_slice() {
241 let signal1 = Signal::parse(
242 &mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap(),
243 )
244 .unwrap();
245 let signal2 = Signal::parse(
246 &mut Parser::new(b"SG_ Signal2 : 8|8@0+ (1,0) [0|255] \"\"").unwrap(),
247 )
248 .unwrap();
249
250 let signals = Signals::from_signals_slice(&[signal1, signal2]);
251 assert_eq!(signals.len(), 2);
252 assert!(!signals.is_empty());
253 assert_eq!(signals.at(0).unwrap().name(), "Signal1");
254 assert_eq!(signals.at(1).unwrap().name(), "Signal2");
255 }
256
257 #[test]
258 fn test_signals_from_signals_slice_empty() {
259 let signals = Signals::from_signals_slice(&[]);
260 assert_eq!(signals.len(), 0);
261 assert!(signals.is_empty());
262 assert!(signals.at(0).is_none());
263 }
264
265 #[test]
266 fn test_signals_from_signals_slice_multiple() {
267 let signal1 = Signal::parse(
269 &mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap(),
270 )
271 .unwrap();
272 let signal2 = Signal::parse(
273 &mut Parser::new(b"SG_ Signal2 : 8|8@0+ (1,0) [0|255] \"\"").unwrap(),
274 )
275 .unwrap();
276 let signal3 = Signal::parse(
277 &mut Parser::new(b"SG_ Signal3 : 16|8@0+ (1,0) [0|255] \"\"").unwrap(),
278 )
279 .unwrap();
280
281 let signals = Signals::from_signals_slice(&[signal1, signal2, signal3]);
282 assert_eq!(signals.len(), 3);
283 assert_eq!(signals.at(0).unwrap().name(), "Signal1");
284 assert_eq!(signals.at(1).unwrap().name(), "Signal2");
285 assert_eq!(signals.at(2).unwrap().name(), "Signal3");
286 }
287 }
288
289 #[test]
290 fn test_signals_from_options_slice() {
291 let signal1 =
292 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap())
293 .unwrap();
294 let signal2 =
295 Signal::parse(&mut Parser::new(b"SG_ Signal2 : 8|8@0+ (1,0) [0|255] \"\"").unwrap())
296 .unwrap();
297
298 const MAX_CAP: usize = Signals::max_capacity();
299 let mut options: [Option<Signal>; MAX_CAP] = [const { None }; MAX_CAP];
300 options[0] = Some(signal1);
301 options[1] = Some(signal2);
302
303 let signals = Signals::from_options_slice(&options, 2);
304 assert_eq!(signals.len(), 2);
305 assert_eq!(signals.at(0).unwrap().name(), "Signal1");
306 assert_eq!(signals.at(1).unwrap().name(), "Signal2");
307 }
308
309 #[test]
310 fn test_signals_from_options_slice_with_none() {
311 let signal1 =
312 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap())
313 .unwrap();
314
315 const MAX_CAP: usize = Signals::max_capacity();
316 let mut options: [Option<Signal>; MAX_CAP] = [const { None }; MAX_CAP];
317 options[0] = Some(signal1);
318 options[1] = None; options[2] = Some(
320 Signal::parse(&mut Parser::new(b"SG_ Signal3 : 16|8@0+ (1,0) [0|255] \"\"").unwrap())
321 .unwrap(),
322 );
323
324 let signals = Signals::from_options_slice(&options, 3);
325 assert_eq!(signals.len(), 3);
326 assert_eq!(signals.at(0).unwrap().name(), "Signal1");
327 assert!(signals.at(1).is_none()); assert_eq!(signals.at(2).unwrap().name(), "Signal3");
329 }
330
331 #[test]
332 fn test_signals_from_options_slice_count_less_than_length() {
333 let signal1 =
334 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap())
335 .unwrap();
336
337 const MAX_CAP: usize = Signals::max_capacity();
338 let mut options: [Option<Signal>; MAX_CAP] = [const { None }; MAX_CAP];
339 options[0] = Some(signal1);
340 options[1] = Some(
342 Signal::parse(&mut Parser::new(b"SG_ Signal2 : 8|8@0+ (1,0) [0|255] \"\"").unwrap())
343 .unwrap(),
344 );
345
346 let signals = Signals::from_options_slice(&options, 1);
347 assert_eq!(signals.len(), 1);
348 assert_eq!(signals.at(0).unwrap().name(), "Signal1");
349 assert!(signals.at(1).is_none());
350 }
351
352 #[test]
353 fn test_signals_find_not_found() {
354 let signal1 =
355 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap())
356 .unwrap();
357
358 const MAX_CAP: usize = Signals::max_capacity();
359 let mut options: [Option<Signal>; MAX_CAP] = [const { None }; MAX_CAP];
360 options[0] = Some(signal1);
361
362 let signals = Signals::from_options_slice(&options, 1);
363 assert!(signals.find("Nonexistent").is_none());
364 assert!(signals.find("").is_none());
365 assert!(signals.find("signal1").is_none()); }
367
368 #[test]
369 fn test_signals_find_first_match() {
370 let signal1 =
371 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap())
372 .unwrap();
373 let signal2 =
374 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 8|8@0+ (1,0) [0|255] \"\"").unwrap())
375 .unwrap(); const MAX_CAP: usize = Signals::max_capacity();
378 let mut options: [Option<Signal>; MAX_CAP] = [const { None }; MAX_CAP];
379 options[0] = Some(signal1);
380 options[1] = Some(signal2);
381
382 let signals = Signals::from_options_slice(&options, 2);
383 let found = signals.find("Signal1");
385 assert!(found.is_some());
386 assert_eq!(found.unwrap().start_bit(), 0); }
388
389 #[test]
390 fn test_signals_iter_empty() {
391 const MAX_CAP: usize = Signals::max_capacity();
392 let options: [Option<Signal>; MAX_CAP] = [const { None }; MAX_CAP];
393 let signals = Signals::from_options_slice(&options, 0);
394
395 let mut iter = signals.iter();
396 assert!(iter.next().is_none());
397 assert_eq!(signals.len(), 0);
398 assert!(signals.is_empty());
399 }
400
401 #[test]
402 fn test_signals_iter_skips_none() {
403 let signal1 =
404 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap())
405 .unwrap();
406 let signal2 =
407 Signal::parse(&mut Parser::new(b"SG_ Signal2 : 16|8@0+ (1,0) [0|255] \"\"").unwrap())
408 .unwrap();
409
410 const MAX_CAP: usize = Signals::max_capacity();
411 let mut options: [Option<Signal>; MAX_CAP] = [const { None }; MAX_CAP];
412 options[0] = Some(signal1);
413 options[1] = None; options[2] = Some(signal2);
415
416 let signals = Signals::from_options_slice(&options, 3);
417 let mut iter = signals.iter();
418 assert_eq!(iter.next().unwrap().name(), "Signal1");
419 assert_eq!(iter.next().unwrap().name(), "Signal2");
420 assert!(iter.next().is_none());
421 }
422
423 #[test]
424 fn test_signals_at_with_gaps() {
425 let signal1 =
426 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap())
427 .unwrap();
428
429 const MAX_CAP: usize = Signals::max_capacity();
430 let mut options: [Option<Signal>; MAX_CAP] = [const { None }; MAX_CAP];
431 options[0] = Some(signal1);
432 options[1] = None;
433
434 let signals = Signals::from_options_slice(&options, 2);
435 assert_eq!(signals.at(0).unwrap().name(), "Signal1");
436 assert!(signals.at(1).is_none()); }
438
439 #[cfg(not(any(feature = "alloc", feature = "kernel")))]
441 mod tests_no_alloc {
442 use super::*;
443
444 #[test]
445 fn test_signals_new_parse_buffer() {
446 let buffer = Signals::new_parse_buffer();
447 assert_eq!(buffer.len(), Signals::max_capacity());
448 for opt in buffer.iter() {
450 assert!(opt.is_none());
451 }
452 }
453 }
454}