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}