dbc_rs/receivers/core.rs
1use super::Receivers;
2use crate::{
3 MAX_NAME_SIZE, MAX_NODES,
4 compat::{String, Vec},
5};
6
7impl Receivers {
8 pub(crate) fn new_broadcast() -> Self {
9 Receivers::Broadcast
10 }
11
12 pub(crate) fn new_none() -> Self {
13 Receivers::None
14 }
15
16 pub(crate) fn new_nodes(nodes: &[String<{ MAX_NAME_SIZE }>]) -> Self {
17 // Validation should have been done prior (by builder or parse)
18 // Receivers can have at most MAX_NODES - 1 nodes
19 let vec_nodes: Vec<String<{ MAX_NAME_SIZE }>, { MAX_NODES - 1 }> =
20 nodes.iter().take(MAX_NODES - 1).cloned().collect();
21 Receivers::Nodes(vec_nodes)
22 }
23
24 /// Returns an iterator over the receiver node names.
25 ///
26 /// For `Receivers::Broadcast` and `Receivers::None`, the iterator will be empty.
27 /// For `Receivers::Nodes`, it iterates over the specific node names.
28 ///
29 /// # Examples
30 ///
31 /// ```rust,no_run
32 /// use dbc_rs::Dbc;
33 ///
34 /// let dbc = Dbc::parse(r#"VERSION "1.0"
35 ///
36 /// BU_: ECM TCM BCM
37 ///
38 /// BO_ 256 Engine : 8 ECM
39 /// SG_ Temp : 0|8@1+ (1,0) [0|255] "°C" TCM BCM
40 /// "#)?;
41 ///
42 /// let message = dbc.messages().at(0).unwrap();
43 /// let signal = message.signals().at(0).unwrap();
44 ///
45 /// // Iterate over receiver nodes
46 /// let mut iter = signal.receivers().iter();
47 /// assert_eq!(iter.next().map(|s| s.to_string()), Some("TCM".to_string()));
48 /// assert_eq!(iter.next().map(|s| s.to_string()), Some("BCM".to_string()));
49 /// assert_eq!(iter.next(), None);
50 /// # Ok::<(), dbc_rs::Error>(())
51 /// ```
52 ///
53 /// # Broadcast and None
54 ///
55 /// ```rust,no_run
56 /// use dbc_rs::Dbc;
57 ///
58 /// let dbc = Dbc::parse(r#"VERSION "1.0"
59 ///
60 /// BU_: ECM
61 ///
62 /// BO_ 256 Engine : 8 ECM
63 /// SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm" *
64 /// "#)?;
65 ///
66 /// let message = dbc.messages().at(0).unwrap();
67 /// let signal = message.signals().at(0).unwrap();
68 ///
69 /// // Broadcast receivers return empty iterator
70 /// assert_eq!(signal.receivers().iter().count(), 0);
71 /// # Ok::<(), dbc_rs::Error>(())
72 /// ```
73 /// Returns an iterator over the receiver node names as borrowed references.
74 ///
75 /// For `Receivers::Broadcast` and `Receivers::None`, the iterator will be empty.
76 /// For `Receivers::Nodes`, it iterates over the specific node names.
77 ///
78 /// # Examples
79 ///
80 /// ```rust,no_run
81 /// use dbc_rs::Dbc;
82 ///
83 /// let dbc = Dbc::parse(r#"VERSION "1.0"
84 ///
85 /// BU_: ECM TCM BCM
86 ///
87 /// BO_ 256 Engine : 8 ECM
88 /// SG_ Temp : 0|8@1+ (1,0) [0|255] "°C" TCM BCM
89 /// "#)?;
90 ///
91 /// let message = dbc.messages().at(0).unwrap();
92 /// let signal = message.signals().at(0).unwrap();
93 ///
94 /// // Iterate over receiver nodes
95 /// let mut iter = signal.receivers().iter();
96 /// assert_eq!(iter.next(), Some("TCM"));
97 /// assert_eq!(iter.next(), Some("BCM"));
98 /// assert_eq!(iter.next(), None);
99 /// # Ok::<(), dbc_rs::Error>(())
100 /// ```
101 ///
102 /// # Broadcast and None
103 ///
104 /// ```rust,no_run
105 /// use dbc_rs::Dbc;
106 ///
107 /// let dbc = Dbc::parse(r#"VERSION "1.0"
108 ///
109 /// BU_: ECM
110 ///
111 /// BO_ 256 Engine : 8 ECM
112 /// SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm" *
113 /// "#)?;
114 ///
115 /// let message = dbc.messages().at(0).unwrap();
116 /// let signal = message.signals().at(0).unwrap();
117 ///
118 /// // Broadcast receivers return empty iterator
119 /// assert_eq!(signal.receivers().iter().count(), 0);
120 /// # Ok::<(), dbc_rs::Error>(())
121 /// ```
122 #[inline]
123 #[must_use = "iterator is lazy and does nothing unless consumed"]
124 pub fn iter(&self) -> impl Iterator<Item = &str> {
125 match self {
126 Receivers::Nodes(nodes) => ReceiversIter {
127 nodes: Some(nodes.as_slice()),
128 pos: 0,
129 },
130 _ => ReceiversIter {
131 nodes: None,
132 pos: 0,
133 },
134 }
135 }
136
137 /// Returns the number of receiver nodes.
138 ///
139 /// - For `Receivers::Nodes`: Returns the count of specific receiver nodes
140 /// - For `Receivers::Broadcast` and `Receivers::None`: Returns `0`
141 ///
142 /// # Examples
143 ///
144 /// ```rust,no_run
145 /// use dbc_rs::Dbc;
146 ///
147 /// let dbc = Dbc::parse(r#"VERSION "1.0"
148 ///
149 /// BU_: ECM TCM BCM
150 ///
151 /// BO_ 256 Engine : 8 ECM
152 /// SG_ Temp : 0|8@1+ (1,0) [0|255] "°C" TCM BCM
153 /// "#)?;
154 ///
155 /// let message = dbc.messages().at(0).unwrap();
156 /// let signal = message.signals().at(0).unwrap();
157 /// assert_eq!(signal.receivers().len(), 2);
158 /// # Ok::<(), dbc_rs::Error>(())
159 /// ```
160 #[inline]
161 #[must_use = "return value should be used"]
162 pub fn len(&self) -> usize {
163 match self {
164 Receivers::Nodes(nodes) => nodes.len(),
165 Receivers::Broadcast | Receivers::None => 0,
166 }
167 }
168
169 /// Returns `true` if there are no specific receiver nodes.
170 ///
171 /// This returns `true` for both `Receivers::Broadcast` and `Receivers::None`,
172 /// as neither has specific node names.
173 ///
174 /// # Examples
175 ///
176 /// ```rust,no_run
177 /// use dbc_rs::Dbc;
178 ///
179 /// let dbc = Dbc::parse(r#"VERSION "1.0"
180 ///
181 /// BU_: ECM
182 ///
183 /// BO_ 256 Engine : 8 ECM
184 /// SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm"
185 /// "#)?;
186 ///
187 /// let message = dbc.messages().at(0).unwrap();
188 /// let signal = message.signals().at(0).unwrap();
189 /// assert!(signal.receivers().is_empty());
190 /// # Ok::<(), dbc_rs::Error>(())
191 /// ```
192 #[inline]
193 #[must_use = "return value should be used"]
194 pub fn is_empty(&self) -> bool {
195 self.len() == 0
196 }
197
198 /// Checks if a node name is in the receivers list.
199 ///
200 /// For `Receivers::Broadcast` and `Receivers::None`, this always returns `false`.
201 /// For `Receivers::Nodes`, it checks if the node name is in the list.
202 ///
203 /// # Arguments
204 ///
205 /// * `node` - The node name to check
206 ///
207 /// # Examples
208 ///
209 /// ```rust,no_run
210 /// use dbc_rs::Dbc;
211 ///
212 /// let dbc = Dbc::parse(r#"VERSION "1.0"
213 ///
214 /// BU_: ECM TCM BCM
215 ///
216 /// BO_ 256 Engine : 8 ECM
217 /// SG_ Temp : 0|8@1+ (1,0) [0|255] "°C" TCM BCM
218 /// "#)?;
219 ///
220 /// let message = dbc.messages().at(0).unwrap();
221 /// let signal = message.signals().at(0).unwrap();
222 ///
223 /// assert!(signal.receivers().contains("TCM"));
224 /// assert!(signal.receivers().contains("BCM"));
225 /// assert!(!signal.receivers().contains("ECM"));
226 /// # Ok::<(), dbc_rs::Error>(())
227 /// ```
228 #[inline]
229 #[must_use = "return value should be used"]
230 pub fn contains(&self, node: &str) -> bool {
231 self.iter().any(|n| n == node)
232 }
233
234 /// Gets a receiver node by index.
235 ///
236 /// Returns `None` if:
237 /// - The index is out of bounds
238 /// - The receiver is `Broadcast` or `None`
239 ///
240 /// # Arguments
241 ///
242 /// * `index` - The zero-based index of the receiver node
243 ///
244 /// # Examples
245 ///
246 /// ```rust,no_run
247 /// use dbc_rs::Dbc;
248 ///
249 /// let dbc = Dbc::parse(r#"VERSION "1.0"
250 ///
251 /// BU_: ECM TCM BCM
252 ///
253 /// BO_ 256 Engine : 8 ECM
254 /// SG_ Temp : 0|8@1+ (1,0) [0|255] "°C" TCM BCM
255 /// "#)?;
256 ///
257 /// let message = dbc.messages().at(0).unwrap();
258 /// let signal = message.signals().at(0).unwrap();
259 ///
260 /// assert_eq!(signal.receivers().at(0), Some("TCM"));
261 /// assert_eq!(signal.receivers().at(1), Some("BCM"));
262 /// assert_eq!(signal.receivers().at(2), None);
263 /// # Ok::<(), dbc_rs::Error>(())
264 /// ```
265 #[inline]
266 #[must_use = "return value should be used"]
267 pub fn at(&self, index: usize) -> Option<&str> {
268 match self {
269 Receivers::Nodes(nodes) => nodes.get(index).map(|s| s.as_str()),
270 Receivers::Broadcast | Receivers::None => None,
271 }
272 }
273}
274
275struct ReceiversIter<'a> {
276 nodes: Option<&'a [String<{ MAX_NAME_SIZE }>]>,
277 pos: usize,
278}
279
280impl<'a> Iterator for ReceiversIter<'a> {
281 type Item = &'a str;
282 fn next(&mut self) -> Option<Self::Item> {
283 if let Some(nodes) = self.nodes {
284 if self.pos < nodes.len() {
285 let result = nodes[self.pos].as_str();
286 self.pos += 1;
287 Some(result)
288 } else {
289 None
290 }
291 } else {
292 None
293 }
294 }
295}
296
297#[cfg(test)]
298mod tests {
299 use super::Receivers;
300 use crate::Parser;
301
302 // Tests for new_broadcast()
303 mod test_new_broadcast {
304 use super::*;
305
306 #[test]
307 fn test_receivers_broadcast() {
308 let broadcast = Receivers::new_broadcast();
309 assert_eq!(broadcast.len(), 0);
310 assert!(broadcast.is_empty());
311 }
312 }
313
314 // Tests for new_none()
315 mod test_new_none {
316 use super::*;
317
318 #[test]
319 fn test_receivers_none() {
320 let none = Receivers::new_none();
321 assert_eq!(none.len(), 0);
322 assert!(none.is_empty());
323 }
324 }
325
326 // Tests for iter()
327 mod test_iter {
328 use super::*;
329
330 #[test]
331 fn test_receivers_iter() {
332 let input = "TCM BCM";
333 let mut parser = Parser::new(input.as_bytes()).unwrap();
334 let result = Receivers::parse(&mut parser).unwrap();
335 let mut iter = result.iter();
336 assert_eq!(iter.next(), Some("TCM"));
337 assert_eq!(iter.next(), Some("BCM"));
338 assert!(iter.next().is_none());
339
340 let broadcast = Receivers::new_broadcast();
341 assert_eq!(broadcast.iter().count(), 0);
342
343 let none = Receivers::new_none();
344 assert_eq!(none.iter().count(), 0);
345 }
346 }
347
348 // Tests for len()
349 mod test_len {
350 use super::*;
351
352 #[test]
353 fn test_receivers_len() {
354 let broadcast = Receivers::new_broadcast();
355 assert_eq!(broadcast.len(), 0);
356
357 let none = Receivers::new_none();
358 assert_eq!(none.len(), 0);
359
360 let input = "TCM BCM";
361 let mut parser = Parser::new(input.as_bytes()).unwrap();
362 let nodes = Receivers::parse(&mut parser).unwrap();
363 assert_eq!(nodes.len(), 2);
364 }
365 }
366
367 // Tests for is_empty()
368 mod test_is_empty {
369 use super::*;
370
371 #[test]
372 fn test_receivers_is_empty() {
373 let broadcast = Receivers::new_broadcast();
374 assert!(broadcast.is_empty());
375
376 let none = Receivers::new_none();
377 assert!(none.is_empty());
378
379 let input = "TCM";
380 let mut parser = Parser::new(input.as_bytes()).unwrap();
381 let nodes = Receivers::parse(&mut parser).unwrap();
382 assert!(!nodes.is_empty());
383 }
384 }
385
386 // Tests for contains()
387 mod test_contains {
388 use super::*;
389
390 #[test]
391 fn test_receivers_contains() {
392 let input = "TCM BCM";
393 let mut parser = Parser::new(input.as_bytes()).unwrap();
394 let result = Receivers::parse(&mut parser).unwrap();
395 assert!(result.contains("TCM"));
396 assert!(result.contains("BCM"));
397 assert!(!result.contains("ECM"));
398
399 let broadcast = Receivers::new_broadcast();
400 assert!(!broadcast.contains("TCM"));
401
402 let none = Receivers::new_none();
403 assert!(!none.contains("TCM"));
404 }
405 }
406
407 // Tests for at()
408 mod test_at {
409 use super::*;
410
411 #[test]
412 fn test_receivers_at() {
413 let input = "TCM BCM";
414 let mut parser = Parser::new(input.as_bytes()).unwrap();
415 let result = Receivers::parse(&mut parser).unwrap();
416 assert_eq!(result.at(0), Some("TCM"));
417 assert_eq!(result.at(1), Some("BCM"));
418 assert_eq!(result.at(2), None);
419
420 let broadcast = Receivers::new_broadcast();
421 assert_eq!(broadcast.at(0), None);
422
423 let none = Receivers::new_none();
424 assert_eq!(none.at(0), None);
425 }
426 }
427}