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}