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}