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}