Skip to main content

dbc_rs/receivers/
impls.rs

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