dbc_rs/value_descriptions/core.rs
1use super::ValueDescriptions;
2use std::{string::String, vec::Vec};
3
4use crate::MAX_VALUE_DESCRIPTIONS;
5
6impl ValueDescriptions {
7 /// Create ValueDescriptions from a slice of (value, description) pairs
8 pub(crate) fn from_slice(entries: &[(u64, String)]) -> Self {
9 let count = entries.len().min(MAX_VALUE_DESCRIPTIONS);
10 let vec_entries: Vec<(u64, String)> =
11 entries.iter().take(count).map(|(value, desc)| (*value, desc.clone())).collect();
12 Self {
13 entries: vec_entries,
14 }
15 }
16
17 /// Get the description for a numeric value
18 ///
19 /// # Examples
20 ///
21 /// ```rust,no_run
22 /// # use dbc_rs::Dbc;
23 /// # let dbc = Dbc::parse(r#"VERSION "1.0"\n\nBU_: ECM\n\nBO_ 100 Engine : 8 ECM\n SG_ Gear : 0|8@1+ (1,0) [0|5] "" *\n\nVAL_ 100 Gear 0 "Park" 1 "Reverse" ;"#)?;
24 /// # let message = dbc.messages().iter().next().unwrap();
25 /// # let signal = message.signals().iter().next().unwrap();
26 /// if let Some(value_descriptions) = dbc.value_descriptions_for_signal(message.id(), signal.name()) {
27 /// if let Some(desc) = value_descriptions.get(0) {
28 /// println!("Value 0: {}", desc);
29 /// }
30 /// }
31 /// # Ok::<(), dbc_rs::Error>(())
32 /// ```
33 #[must_use = "return value should be used"]
34 pub fn get(&self, value: u64) -> Option<&str> {
35 for (v, desc) in &self.entries {
36 if *v == value {
37 return Some(desc.as_ref());
38 }
39 }
40 None
41 }
42
43 /// Get the number of value descriptions
44 #[must_use = "return value should be used"]
45 pub fn len(&self) -> usize {
46 self.entries.len()
47 }
48
49 /// Check if there are any value descriptions
50 #[must_use = "return value should be used"]
51 pub fn is_empty(&self) -> bool {
52 self.entries.is_empty()
53 }
54
55 /// Get a value description by index.
56 ///
57 /// Returns `None` if the index is out of bounds.
58 ///
59 /// # Arguments
60 ///
61 /// * `index` - The zero-based index of the value description
62 ///
63 /// # Examples
64 ///
65 /// ```rust,no_run
66 /// # use dbc_rs::Dbc;
67 /// # let dbc = Dbc::parse(r#"VERSION "1.0"\n\nBU_: ECM\n\nBO_ 100 Engine : 8 ECM\n SG_ Gear : 0|8@1+ (1,0) [0|5] "" *\n\nVAL_ 100 Gear 0 "Park" 1 "Reverse" ;"#)?;
68 /// # let message = dbc.messages().iter().next().unwrap();
69 /// # let signal = message.signals().iter().next().unwrap();
70 /// if let Some(value_descriptions) = dbc.value_descriptions_for_signal(message.id(), signal.name()) {
71 /// if let Some((value, description)) = value_descriptions.at(0) {
72 /// println!("Value {}: {}", value, description);
73 /// }
74 /// }
75 /// # Ok::<(), dbc_rs::Error>(())
76 /// ```
77 #[must_use = "return value should be used"]
78 pub fn at(&self, index: usize) -> Option<(u64, &str)> {
79 self.entries.get(index).map(|(value, desc)| (*value, desc.as_str()))
80 }
81
82 /// Iterate over all value descriptions
83 ///
84 /// # Examples
85 ///
86 /// ```rust,no_run
87 /// # use dbc_rs::Dbc;
88 /// # let dbc = Dbc::parse(r#"VERSION "1.0"\n\nBU_: ECM\n\nBO_ 100 Engine : 8 ECM\n SG_ Gear : 0|8@1+ (1,0) [0|5] "" *\n\nVAL_ 100 Gear 0 "Park" 1 "Reverse" ;"#)?;
89 /// # let message = dbc.messages().iter().next().unwrap();
90 /// # let signal = message.signals().iter().next().unwrap();
91 /// if let Some(value_descriptions) = dbc.value_descriptions_for_signal(message.id(), signal.name()) {
92 /// for (value, description) in value_descriptions.iter() {
93 /// println!("{} -> {}", value, description);
94 /// }
95 /// }
96 /// # Ok::<(), dbc_rs::Error>(())
97 /// ```
98 #[must_use = "iterator is lazy and does nothing unless consumed"]
99 pub fn iter(&self) -> ValueDescriptionsIter<'_> {
100 ValueDescriptionsIter {
101 entries: &self.entries,
102 pos: 0,
103 }
104 }
105}
106
107/// Iterator over value descriptions
108pub struct ValueDescriptionsIter<'a> {
109 entries: &'a [(u64, String)],
110 pos: usize,
111}
112
113impl<'a> Iterator for ValueDescriptionsIter<'a> {
114 type Item = (u64, &'a str);
115
116 fn next(&mut self) -> Option<Self::Item> {
117 if self.pos < self.entries.len() {
118 let entry = &self.entries[self.pos];
119 let result = (entry.0, entry.1.as_str());
120 self.pos += 1;
121 Some(result)
122 } else {
123 None
124 }
125 }
126}