dbc_rs/message/
signal_list.rs1use crate::{MAX_SIGNALS_PER_MESSAGE, Signal, compat::Vec};
2
3#[derive(Debug, Clone, PartialEq, Eq, Hash)]
7pub struct SignalList {
8 signals: Vec<Signal, { MAX_SIGNALS_PER_MESSAGE }>,
9}
10
11impl From<&[Signal]> for SignalList {
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 SignalList {
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 SignalList {
25 fn from(signals: Vec<Signal, { MAX_SIGNALS_PER_MESSAGE }>) -> Self {
26 Self::from_slice(signals.as_slice())
27 }
28}
29
30impl SignalList {
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]
75 pub fn len(&self) -> usize {
76 self.signals.len()
77 }
78
79 #[inline]
92 #[must_use]
93 pub fn is_empty(&self) -> bool {
94 self.len() == 0
95 }
96
97 #[inline]
112 #[must_use]
113 pub fn at(&self, index: usize) -> Option<&Signal> {
114 self.signals.get(index)
115 }
116
117 #[must_use]
133 pub fn find(&self, name: &str) -> Option<&Signal> {
134 self.iter().find(|s| s.name() == name)
135 }
136}
137
138#[cfg(test)]
139mod tests {
140 use super::SignalList;
141 use crate::{Parser, Signal};
142
143 #[cfg(feature = "std")]
145 mod tests_with_std {
146 use super::*;
147
148 #[test]
149 fn test_signals_from_slice() {
150 let signal1 = Signal::parse(
151 &mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap(),
152 )
153 .unwrap();
154 let signal2 = Signal::parse(
155 &mut Parser::new(b"SG_ Signal2 : 8|8@0+ (1,0) [0|255] \"\"").unwrap(),
156 )
157 .unwrap();
158
159 let signals = SignalList::from_slice(&[signal1, signal2]);
160 assert_eq!(signals.len(), 2);
161 assert!(!signals.is_empty());
162 assert_eq!(signals.at(0).unwrap().name(), "Signal1");
163 assert_eq!(signals.at(1).unwrap().name(), "Signal2");
164 }
165
166 #[test]
167 fn test_signals_from_signals_slice_empty() {
168 let signals = SignalList::from_slice(&[]);
169 assert_eq!(signals.len(), 0);
170 assert!(signals.is_empty());
171 assert!(signals.at(0).is_none());
172 }
173
174 #[test]
175 fn test_signals_from_slice_multiple() {
176 let signal1 = Signal::parse(
178 &mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap(),
179 )
180 .unwrap();
181 let signal2 = Signal::parse(
182 &mut Parser::new(b"SG_ Signal2 : 8|8@0+ (1,0) [0|255] \"\"").unwrap(),
183 )
184 .unwrap();
185 let signal3 = Signal::parse(
186 &mut Parser::new(b"SG_ Signal3 : 16|8@0+ (1,0) [0|255] \"\"").unwrap(),
187 )
188 .unwrap();
189
190 let signals = SignalList::from_slice(&[signal1, signal2, signal3]);
191 assert_eq!(signals.len(), 3);
192 assert_eq!(signals.at(0).unwrap().name(), "Signal1");
193 assert_eq!(signals.at(1).unwrap().name(), "Signal2");
194 assert_eq!(signals.at(2).unwrap().name(), "Signal3");
195 }
196 }
197
198 #[test]
199 fn test_signals_find_not_found() {
200 let signal1 =
201 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap())
202 .unwrap();
203
204 let signals = SignalList::from_slice(&[signal1]);
205 assert!(signals.find("Nonexistent").is_none());
206 assert!(signals.find("").is_none());
207 assert!(signals.find("signal1").is_none()); }
209
210 #[test]
211 fn test_signals_find_first_match() {
212 let signal1 =
213 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 0|8@0+ (1,0) [0|255] \"\"").unwrap())
214 .unwrap();
215 let signal2 =
216 Signal::parse(&mut Parser::new(b"SG_ Signal1 : 8|8@0+ (1,0) [0|255] \"\"").unwrap())
217 .unwrap(); let signals = SignalList::from_slice(&[signal1, signal2]);
220 let found = signals.find("Signal1");
222 assert!(found.is_some());
223 assert_eq!(found.unwrap().start_bit(), 0); }
225}