dbc_rs/receivers/core.rs
1use super::Receivers;
2use crate::{
3 MAX_NAME_SIZE, MAX_RECEIVER_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 #[cfg(feature = "std")]
17 pub(crate) fn new_nodes(nodes: &[String<{ MAX_NAME_SIZE }>]) -> Self {
18 // Validation should have been done prior (by builder or parse)
19 let vec_nodes: Vec<String<{ MAX_NAME_SIZE }>, { MAX_RECEIVER_NODES }> =
20 nodes.iter().take(MAX_RECEIVER_NODES).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 #[inline]
74 #[must_use = "iterator is lazy and does nothing unless consumed"]
75 pub fn iter(&self) -> impl Iterator<Item = String<{ MAX_NAME_SIZE }>> {
76 match self {
77 Receivers::Nodes(nodes) => ReceiversIter {
78 nodes: Some(nodes.clone()),
79 pos: 0,
80 },
81 _ => ReceiversIter {
82 nodes: None,
83 pos: 0,
84 },
85 }
86 }
87
88 /// Returns the number of receiver nodes.
89 ///
90 /// - For `Receivers::Nodes`: Returns the count of specific receiver nodes
91 /// - For `Receivers::Broadcast` and `Receivers::None`: Returns `0`
92 ///
93 /// # Examples
94 ///
95 /// ```rust,no_run
96 /// use dbc_rs::Dbc;
97 ///
98 /// let dbc = Dbc::parse(r#"VERSION "1.0"
99 ///
100 /// BU_: ECM TCM BCM
101 ///
102 /// BO_ 256 Engine : 8 ECM
103 /// SG_ Temp : 0|8@1+ (1,0) [0|255] "°C" TCM BCM
104 /// "#)?;
105 ///
106 /// let message = dbc.messages().at(0).unwrap();
107 /// let signal = message.signals().at(0).unwrap();
108 /// assert_eq!(signal.receivers().len(), 2);
109 /// # Ok::<(), dbc_rs::Error>(())
110 /// ```
111 #[inline]
112 #[must_use]
113 pub fn len(&self) -> usize {
114 match self {
115 Receivers::Nodes(nodes) => nodes.len(),
116 Receivers::Broadcast | Receivers::None => 0,
117 }
118 }
119
120 /// Returns `true` if there are no specific receiver nodes.
121 ///
122 /// This returns `true` for both `Receivers::Broadcast` and `Receivers::None`,
123 /// as neither has specific node names.
124 ///
125 /// # Examples
126 ///
127 /// ```rust,no_run
128 /// use dbc_rs::Dbc;
129 ///
130 /// let dbc = Dbc::parse(r#"VERSION "1.0"
131 ///
132 /// BU_: ECM
133 ///
134 /// BO_ 256 Engine : 8 ECM
135 /// SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm"
136 /// "#)?;
137 ///
138 /// let message = dbc.messages().at(0).unwrap();
139 /// let signal = message.signals().at(0).unwrap();
140 /// assert!(signal.receivers().is_empty());
141 /// # Ok::<(), dbc_rs::Error>(())
142 /// ```
143 #[inline]
144 #[must_use]
145 pub fn is_empty(&self) -> bool {
146 self.len() == 0
147 }
148
149 /// Checks if a node name is in the receivers list.
150 ///
151 /// For `Receivers::Broadcast` and `Receivers::None`, this always returns `false`.
152 /// For `Receivers::Nodes`, it checks if the node name is in the list.
153 ///
154 /// # Arguments
155 ///
156 /// * `node` - The node name to check
157 ///
158 /// # Examples
159 ///
160 /// ```rust,no_run
161 /// use dbc_rs::Dbc;
162 ///
163 /// let dbc = Dbc::parse(r#"VERSION "1.0"
164 ///
165 /// BU_: ECM TCM BCM
166 ///
167 /// BO_ 256 Engine : 8 ECM
168 /// SG_ Temp : 0|8@1+ (1,0) [0|255] "°C" TCM BCM
169 /// "#)?;
170 ///
171 /// let message = dbc.messages().at(0).unwrap();
172 /// let signal = message.signals().at(0).unwrap();
173 ///
174 /// assert!(signal.receivers().contains("TCM"));
175 /// assert!(signal.receivers().contains("BCM"));
176 /// assert!(!signal.receivers().contains("ECM"));
177 /// # Ok::<(), dbc_rs::Error>(())
178 /// ```
179 #[inline]
180 #[must_use]
181 pub fn contains(&self, node: &str) -> bool {
182 self.iter().any(|n| n.as_str() == node)
183 }
184
185 /// Gets a receiver node by index.
186 ///
187 /// Returns `None` if:
188 /// - The index is out of bounds
189 /// - The receiver is `Broadcast` or `None`
190 ///
191 /// # Arguments
192 ///
193 /// * `index` - The zero-based index of the receiver node
194 ///
195 /// # Examples
196 ///
197 /// ```rust,no_run
198 /// use dbc_rs::Dbc;
199 ///
200 /// let dbc = Dbc::parse(r#"VERSION "1.0"
201 ///
202 /// BU_: ECM TCM BCM
203 ///
204 /// BO_ 256 Engine : 8 ECM
205 /// SG_ Temp : 0|8@1+ (1,0) [0|255] "°C" TCM BCM
206 /// "#)?;
207 ///
208 /// let message = dbc.messages().at(0).unwrap();
209 /// let signal = message.signals().at(0).unwrap();
210 ///
211 /// assert_eq!(signal.receivers().at(0), Some("TCM"));
212 /// assert_eq!(signal.receivers().at(1), Some("BCM"));
213 /// assert_eq!(signal.receivers().at(2), None);
214 /// # Ok::<(), dbc_rs::Error>(())
215 /// ```
216 #[inline]
217 #[must_use]
218 pub fn at(&self, index: usize) -> Option<&str> {
219 match self {
220 Receivers::Nodes(nodes) => nodes.get(index).map(|s| s.as_str()),
221 Receivers::Broadcast | Receivers::None => None,
222 }
223 }
224}
225
226struct ReceiversIter {
227 nodes: Option<Vec<String<{ MAX_NAME_SIZE }>, { MAX_RECEIVER_NODES }>>,
228 pos: usize,
229}
230
231impl Iterator for ReceiversIter {
232 type Item = String<{ MAX_NAME_SIZE }>;
233 fn next(&mut self) -> Option<Self::Item> {
234 if let Some(nodes) = &self.nodes {
235 if self.pos < nodes.len() {
236 let result: String<{ MAX_NAME_SIZE }> = nodes[self.pos].clone();
237 self.pos += 1;
238 Some(result)
239 } else {
240 None
241 }
242 } else {
243 None
244 }
245 }
246}
247
248#[cfg(test)]
249mod tests {
250 use super::Receivers;
251 use crate::Parser;
252
253 // Tests for new_broadcast()
254 mod test_new_broadcast {
255 use super::*;
256
257 #[test]
258 fn test_receivers_broadcast() {
259 let broadcast = Receivers::new_broadcast();
260 assert_eq!(broadcast.len(), 0);
261 assert!(broadcast.is_empty());
262 }
263 }
264
265 // Tests for new_none()
266 mod test_new_none {
267 use super::*;
268
269 #[test]
270 fn test_receivers_none() {
271 let none = Receivers::new_none();
272 assert_eq!(none.len(), 0);
273 assert!(none.is_empty());
274 }
275 }
276
277 // Tests for iter()
278 mod test_iter {
279 use super::*;
280
281 #[test]
282 fn test_receivers_iter() {
283 let input = "TCM BCM";
284 let mut parser = Parser::new(input.as_bytes()).unwrap();
285 let result = Receivers::parse(&mut parser).unwrap();
286 let mut iter = result.iter();
287 assert_eq!(iter.next().unwrap().as_str(), "TCM");
288 assert_eq!(iter.next().unwrap().as_str(), "BCM");
289 assert!(iter.next().is_none());
290
291 let broadcast = Receivers::new_broadcast();
292 assert_eq!(broadcast.iter().count(), 0);
293
294 let none = Receivers::new_none();
295 assert_eq!(none.iter().count(), 0);
296 }
297 }
298
299 // Tests for len()
300 mod test_len {
301 use super::*;
302
303 #[test]
304 fn test_receivers_len() {
305 let broadcast = Receivers::new_broadcast();
306 assert_eq!(broadcast.len(), 0);
307
308 let none = Receivers::new_none();
309 assert_eq!(none.len(), 0);
310
311 let input = "TCM BCM";
312 let mut parser = Parser::new(input.as_bytes()).unwrap();
313 let nodes = Receivers::parse(&mut parser).unwrap();
314 assert_eq!(nodes.len(), 2);
315 }
316 }
317
318 // Tests for is_empty()
319 mod test_is_empty {
320 use super::*;
321
322 #[test]
323 fn test_receivers_is_empty() {
324 let broadcast = Receivers::new_broadcast();
325 assert!(broadcast.is_empty());
326
327 let none = Receivers::new_none();
328 assert!(none.is_empty());
329
330 let input = "TCM";
331 let mut parser = Parser::new(input.as_bytes()).unwrap();
332 let nodes = Receivers::parse(&mut parser).unwrap();
333 assert!(!nodes.is_empty());
334 }
335 }
336
337 // Tests for contains()
338 mod test_contains {
339 use super::*;
340
341 #[test]
342 fn test_receivers_contains() {
343 let input = "TCM BCM";
344 let mut parser = Parser::new(input.as_bytes()).unwrap();
345 let result = Receivers::parse(&mut parser).unwrap();
346 assert!(result.contains("TCM"));
347 assert!(result.contains("BCM"));
348 assert!(!result.contains("ECM"));
349
350 let broadcast = Receivers::new_broadcast();
351 assert!(!broadcast.contains("TCM"));
352
353 let none = Receivers::new_none();
354 assert!(!none.contains("TCM"));
355 }
356 }
357
358 // Tests for at()
359 mod test_at {
360 use super::*;
361
362 #[test]
363 fn test_receivers_at() {
364 let input = "TCM BCM";
365 let mut parser = Parser::new(input.as_bytes()).unwrap();
366 let result = Receivers::parse(&mut parser).unwrap();
367 assert_eq!(result.at(0), Some("TCM"));
368 assert_eq!(result.at(1), Some("BCM"));
369 assert_eq!(result.at(2), None);
370
371 let broadcast = Receivers::new_broadcast();
372 assert_eq!(broadcast.at(0), None);
373
374 let none = Receivers::new_none();
375 assert_eq!(none.at(0), None);
376 }
377 }
378}