dbc_rs/receivers/
impls.rs

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