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 #[allow(dead_code)] 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 crate::compat::vec_with_capacity;
74 use alloc::vec::Vec;
75 let mut signals_vec: Vec<Option<Signal<'a>>> = vec_with_capacity(count);
76 for signal in signals.iter().take(count) {
77 signals_vec.push(Some(signal.clone()));
78 }
79 Self {
80 signals: signals_vec.into_boxed_slice(),
81 signal_count: count,
82 }
83 }
84 }
85
86 pub(crate) fn from_options_slice(signals: &[Option<Signal<'a>>], signal_count: usize) -> Self {
88 let count = signal_count.min(MAX_SIGNALS_PER_MESSAGE).min(signals.len());
89
90 #[cfg(not(any(feature = "alloc", feature = "kernel")))]
91 {
92 let mut signals_array: [Option<Signal<'a>>; MAX_SIGNALS_PER_MESSAGE] =
93 [const { None }; MAX_SIGNALS_PER_MESSAGE];
94 for (i, signal_opt) in signals.iter().take(count).enumerate() {
95 signals_array[i] = signal_opt.clone();
96 }
97 Self {
98 signals: signals_array,
99 signal_count: count,
100 }
101 }
102
103 #[cfg(any(feature = "alloc", feature = "kernel"))]
104 {
105 use crate::compat::vec_with_capacity;
106 use alloc::vec::Vec;
107 let mut signals_vec: Vec<Option<Signal<'a>>> = vec_with_capacity(count);
108 for signal_opt in signals.iter().take(count) {
109 signals_vec.push(signal_opt.clone());
110 }
111 Self {
112 signals: signals_vec.into_boxed_slice(),
113 signal_count: count,
114 }
115 }
116 }
117
118 #[inline]
133 #[must_use = "iterator is lazy and does nothing unless consumed"]
134 pub fn iter(&self) -> impl Iterator<Item = &Signal<'a>> + '_ {
135 let signals_slice: &[Option<Signal<'a>>] = &self.signals;
136 SignalsIter {
137 signals: signals_slice,
138 count: self.signal_count,
139 pos: 0,
140 }
141 }
142
143 #[inline]
156 #[must_use]
157 pub fn len(&self) -> usize {
158 self.signal_count
159 }
160
161 #[inline]
174 #[must_use]
175 pub fn is_empty(&self) -> bool {
176 self.len() == 0
177 }
178
179 #[inline]
194 #[must_use]
195 pub fn at(&self, index: usize) -> Option<&Signal<'a>> {
196 if index >= self.signal_count {
197 return None;
198 }
199 self.signals[index].as_ref()
200 }
201
202 #[must_use]
218 pub fn find(&self, name: &str) -> Option<&Signal<'a>> {
219 self.iter().find(|s| s.name() == name)
220 }
221
222 pub(crate) const fn max_capacity() -> usize {
224 MAX_SIGNALS_PER_MESSAGE
225 }
226
227 #[cfg(not(any(feature = "alloc", feature = "kernel")))]
230 pub(crate) fn new_parse_buffer<'b>() -> [Option<Signal<'b>>; MAX_SIGNALS_PER_MESSAGE] {
231 [const { None }; MAX_SIGNALS_PER_MESSAGE]
232 }
233}
234
235#[cfg(test)]
236mod tests {
237 use super::Signals;
238 use crate::{Parser, Signal};
239
240 #[cfg(any(feature = "alloc", feature = "kernel"))]
242 mod tests_with_alloc {
243 use super::*;
244
245 #[test]
246 fn test_signals_from_signals_slice() {
247 let signal1 = Signal::parse(
248 &mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap(),
249 )
250 .unwrap();
251 let signal2 = Signal::parse(
252 &mut Parser::new(b"SG_ Signal2 : 8|8@0+ (1,0) [0|255] \"\"").unwrap(),
253 )
254 .unwrap();
255
256 let signals = Signals::from_signals_slice(&[signal1, signal2]);
257 assert_eq!(signals.len(), 2);
258 assert!(!signals.is_empty());
259 assert_eq!(signals.at(0).unwrap().name(), "Signal1");
260 assert_eq!(signals.at(1).unwrap().name(), "Signal2");
261 }
262
263 #[test]
264 fn test_signals_from_signals_slice_empty() {
265 let signals = Signals::from_signals_slice(&[]);
266 assert_eq!(signals.len(), 0);
267 assert!(signals.is_empty());
268 assert!(signals.at(0).is_none());
269 }
270
271 #[test]
272 fn test_signals_from_signals_slice_multiple() {
273 let signal1 = Signal::parse(
275 &mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap(),
276 )
277 .unwrap();
278 let signal2 = Signal::parse(
279 &mut Parser::new(b"SG_ Signal2 : 8|8@0+ (1,0) [0|255] \"\"").unwrap(),
280 )
281 .unwrap();
282 let signal3 = Signal::parse(
283 &mut Parser::new(b"SG_ Signal3 : 16|8@0+ (1,0) [0|255] \"\"").unwrap(),
284 )
285 .unwrap();
286
287 let signals = Signals::from_signals_slice(&[signal1, signal2, signal3]);
288 assert_eq!(signals.len(), 3);
289 assert_eq!(signals.at(0).unwrap().name(), "Signal1");
290 assert_eq!(signals.at(1).unwrap().name(), "Signal2");
291 assert_eq!(signals.at(2).unwrap().name(), "Signal3");
292 }
293 }
294
295 #[test]
296 fn test_signals_from_options_slice() {
297 let signal1 =
298 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap())
299 .unwrap();
300 let signal2 =
301 Signal::parse(&mut Parser::new(b"SG_ Signal2 : 8|8@0+ (1,0) [0|255] \"\"").unwrap())
302 .unwrap();
303
304 const MAX_CAP: usize = Signals::max_capacity();
305 let mut options: [Option<Signal>; MAX_CAP] = [const { None }; MAX_CAP];
306 options[0] = Some(signal1);
307 options[1] = Some(signal2);
308
309 let signals = Signals::from_options_slice(&options, 2);
310 assert_eq!(signals.len(), 2);
311 assert_eq!(signals.at(0).unwrap().name(), "Signal1");
312 assert_eq!(signals.at(1).unwrap().name(), "Signal2");
313 }
314
315 #[test]
316 fn test_signals_from_options_slice_with_none() {
317 let signal1 =
318 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap())
319 .unwrap();
320
321 const MAX_CAP: usize = Signals::max_capacity();
322 let mut options: [Option<Signal>; MAX_CAP] = [const { None }; MAX_CAP];
323 options[0] = Some(signal1);
324 options[1] = None; options[2] = Some(
326 Signal::parse(&mut Parser::new(b"SG_ Signal3 : 16|8@0+ (1,0) [0|255] \"\"").unwrap())
327 .unwrap(),
328 );
329
330 let signals = Signals::from_options_slice(&options, 3);
331 assert_eq!(signals.len(), 3);
332 assert_eq!(signals.at(0).unwrap().name(), "Signal1");
333 assert!(signals.at(1).is_none()); assert_eq!(signals.at(2).unwrap().name(), "Signal3");
335 }
336
337 #[test]
338 fn test_signals_from_options_slice_count_less_than_length() {
339 let signal1 =
340 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap())
341 .unwrap();
342
343 const MAX_CAP: usize = Signals::max_capacity();
344 let mut options: [Option<Signal>; MAX_CAP] = [const { None }; MAX_CAP];
345 options[0] = Some(signal1);
346 options[1] = Some(
348 Signal::parse(&mut Parser::new(b"SG_ Signal2 : 8|8@0+ (1,0) [0|255] \"\"").unwrap())
349 .unwrap(),
350 );
351
352 let signals = Signals::from_options_slice(&options, 1);
353 assert_eq!(signals.len(), 1);
354 assert_eq!(signals.at(0).unwrap().name(), "Signal1");
355 assert!(signals.at(1).is_none());
356 }
357
358 #[test]
359 fn test_signals_find_not_found() {
360 let signal1 =
361 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap())
362 .unwrap();
363
364 const MAX_CAP: usize = Signals::max_capacity();
365 let mut options: [Option<Signal>; MAX_CAP] = [const { None }; MAX_CAP];
366 options[0] = Some(signal1);
367
368 let signals = Signals::from_options_slice(&options, 1);
369 assert!(signals.find("Nonexistent").is_none());
370 assert!(signals.find("").is_none());
371 assert!(signals.find("signal1").is_none()); }
373
374 #[test]
375 fn test_signals_find_first_match() {
376 let signal1 =
377 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap())
378 .unwrap();
379 let signal2 =
380 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 8|8@0+ (1,0) [0|255] \"\"").unwrap())
381 .unwrap(); const MAX_CAP: usize = Signals::max_capacity();
384 let mut options: [Option<Signal>; MAX_CAP] = [const { None }; MAX_CAP];
385 options[0] = Some(signal1);
386 options[1] = Some(signal2);
387
388 let signals = Signals::from_options_slice(&options, 2);
389 let found = signals.find("Signal1");
391 assert!(found.is_some());
392 assert_eq!(found.unwrap().start_bit(), 0); }
394
395 #[test]
396 fn test_signals_iter_empty() {
397 const MAX_CAP: usize = Signals::max_capacity();
398 let options: [Option<Signal>; MAX_CAP] = [const { None }; MAX_CAP];
399 let signals = Signals::from_options_slice(&options, 0);
400
401 let mut iter = signals.iter();
402 assert!(iter.next().is_none());
403 assert_eq!(signals.len(), 0);
404 assert!(signals.is_empty());
405 }
406
407 #[test]
408 fn test_signals_iter_skips_none() {
409 let signal1 =
410 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap())
411 .unwrap();
412 let signal2 =
413 Signal::parse(&mut Parser::new(b"SG_ Signal2 : 16|8@0+ (1,0) [0|255] \"\"").unwrap())
414 .unwrap();
415
416 const MAX_CAP: usize = Signals::max_capacity();
417 let mut options: [Option<Signal>; MAX_CAP] = [const { None }; MAX_CAP];
418 options[0] = Some(signal1);
419 options[1] = None; options[2] = Some(signal2);
421
422 let signals = Signals::from_options_slice(&options, 3);
423 let mut iter = signals.iter();
424 assert_eq!(iter.next().unwrap().name(), "Signal1");
425 assert_eq!(iter.next().unwrap().name(), "Signal2");
426 assert!(iter.next().is_none());
427 }
428
429 #[test]
430 fn test_signals_at_with_gaps() {
431 let signal1 =
432 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap())
433 .unwrap();
434
435 const MAX_CAP: usize = Signals::max_capacity();
436 let mut options: [Option<Signal>; MAX_CAP] = [const { None }; MAX_CAP];
437 options[0] = Some(signal1);
438 options[1] = None;
439
440 let signals = Signals::from_options_slice(&options, 2);
441 assert_eq!(signals.at(0).unwrap().name(), "Signal1");
442 assert!(signals.at(1).is_none()); }
444
445 #[cfg(not(any(feature = "alloc", feature = "kernel")))]
447 mod tests_no_alloc {
448 use super::*;
449
450 #[test]
451 fn test_signals_new_parse_buffer() {
452 let buffer = Signals::new_parse_buffer();
453 assert_eq!(buffer.len(), Signals::max_capacity());
454 for opt in buffer.iter() {
456 assert!(opt.is_none());
457 }
458 }
459 }
460}