dbc_rs/dbc/core.rs
1#[cfg(feature = "std")]
2use super::ValueDescriptionsMap;
3use crate::{Dbc, Nodes, Version, dbc::Messages};
4
5impl Dbc {
6 pub(crate) fn new(
7 version: Option<Version>,
8 nodes: Nodes,
9 messages: Messages,
10 #[cfg(feature = "std")] value_descriptions: ValueDescriptionsMap,
11 ) -> Self {
12 // Validation should have been done prior (by builder)
13 Self {
14 version,
15 nodes,
16 messages,
17 #[cfg(feature = "std")]
18 value_descriptions,
19 }
20 }
21
22 /// Get the version of the DBC file
23 ///
24 /// # Examples
25 ///
26 /// ```rust,no_run
27 /// use dbc_rs::Dbc;
28 ///
29 /// let dbc = Dbc::parse("VERSION \"1.0\"\n\nBU_: ECM\n\nBO_ 256 Engine : 8 ECM")?;
30 /// if let Some(version) = dbc.version() {
31 /// // Version is available
32 /// let _ = version.as_str();
33 /// }
34 /// # Ok::<(), dbc_rs::Error>(())
35 /// ```
36 #[inline]
37 #[must_use]
38 pub fn version(&self) -> Option<&Version> {
39 self.version.as_ref()
40 }
41
42 /// Get a reference to the nodes collection
43 ///
44 /// # Examples
45 ///
46 /// ```rust,no_run
47 /// use dbc_rs::Dbc;
48 ///
49 /// let dbc = Dbc::parse("VERSION \"1.0\"\n\nBU_: ECM TCM\n\nBO_ 256 Engine : 8 ECM")?;
50 /// let nodes = dbc.nodes();
51 /// assert_eq!(nodes.len(), 2);
52 /// // Iterate over nodes
53 /// let mut iter = nodes.iter();
54 /// assert_eq!(iter.next(), Some("ECM"));
55 /// assert_eq!(iter.next(), Some("TCM"));
56 /// assert_eq!(iter.next(), None);
57 /// # Ok::<(), dbc_rs::Error>(())
58 /// ```
59 #[inline]
60 #[must_use]
61 pub fn nodes(&self) -> &Nodes {
62 &self.nodes
63 }
64
65 /// Get a reference to the messages collection
66 ///
67 /// # Examples
68 ///
69 /// ```rust,no_run
70 /// use dbc_rs::Dbc;
71 ///
72 /// let dbc = Dbc::parse("VERSION \"1.0\"\n\nBU_: ECM\n\nBO_ 256 Engine : 8 ECM")?;
73 /// let messages = dbc.messages();
74 /// assert_eq!(messages.len(), 1);
75 /// let message = messages.at(0).unwrap();
76 /// assert_eq!(message.name(), "Engine");
77 /// assert_eq!(message.id(), 256);
78 /// # Ok::<(), dbc_rs::Error>(())
79 /// ```
80 #[inline]
81 #[must_use]
82 pub fn messages(&self) -> &Messages {
83 &self.messages
84 }
85
86 /// Get value descriptions for a specific signal
87 ///
88 /// Value descriptions map numeric signal values to human-readable text.
89 /// Returns `None` if the signal has no value descriptions.
90 ///
91 /// **Global Value Descriptions**: According to the Vector DBC specification,
92 /// a message_id of `-1` (0xFFFFFFFF) in a `VAL_` statement means the value
93 /// descriptions apply to all signals with that name in ANY message. This
94 /// method will first check for a message-specific entry, then fall back to
95 /// a global entry if one exists.
96 ///
97 /// # Examples
98 ///
99 /// ```rust,no_run
100 /// # use dbc_rs::Dbc;
101 /// # 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" ;"#)?;
102 /// if let Some(value_descriptions) = dbc.value_descriptions_for_signal(100, "Gear") {
103 /// if let Some(desc) = value_descriptions.get(0) {
104 /// println!("Value 0 means: {}", desc);
105 /// }
106 /// }
107 /// # Ok::<(), dbc_rs::Error>(())
108 /// ```
109 /// Get a reference to the value descriptions list
110 ///
111 /// # Examples
112 ///
113 /// ```rust,no_run
114 /// use dbc_rs::Dbc;
115 ///
116 /// let dbc = Dbc::parse(r#"VERSION "1.0"
117 ///
118 /// BU_: ECM
119 ///
120 /// BO_ 100 Engine : 8 ECM
121 /// SG_ Gear : 0|8@1+ (1,0) [0|5] "" *
122 ///
123 /// VAL_ 100 Gear 0 "Park" 1 "Drive" ;"#)?;
124 /// let value_descriptions_list = dbc.value_descriptions();
125 /// assert_eq!(value_descriptions_list.len(), 1);
126 /// # Ok::<(), dbc_rs::Error>(())
127 /// ```
128 #[cfg(feature = "std")]
129 #[inline]
130 #[must_use]
131 pub fn value_descriptions(&self) -> &ValueDescriptionsMap {
132 &self.value_descriptions
133 }
134
135 #[cfg(feature = "std")]
136 #[must_use]
137 pub fn value_descriptions_for_signal(
138 &self,
139 message_id: u32,
140 signal_name: &str,
141 ) -> Option<&crate::value_descriptions::ValueDescriptions> {
142 self.value_descriptions.for_signal(message_id, signal_name)
143 }
144}
145
146#[cfg(test)]
147mod tests {
148 use crate::Dbc;
149
150 #[test]
151 fn test_version() {
152 let dbc = Dbc::parse(
153 r#"VERSION "1.0"
154
155BU_: ECM
156
157BO_ 256 Engine : 8 ECM
158"#,
159 )
160 .unwrap();
161 assert_eq!(dbc.version().map(|v| v.as_str()), Some("1.0"));
162 }
163
164 #[test]
165 fn test_nodes() {
166 let dbc = Dbc::parse(
167 r#"VERSION "1.0"
168
169BU_: ECM TCM
170
171BO_ 256 Engine : 8 ECM
172"#,
173 )
174 .unwrap();
175 assert_eq!(dbc.nodes().len(), 2);
176 assert!(dbc.nodes().contains("ECM"));
177 assert!(dbc.nodes().contains("TCM"));
178 }
179
180 #[test]
181 fn test_messages() {
182 let dbc = Dbc::parse(
183 r#"VERSION "1.0"
184
185BU_: ECM
186
187BO_ 256 Engine : 8 ECM
188"#,
189 )
190 .unwrap();
191 assert_eq!(dbc.messages().len(), 1);
192 let message = dbc.messages().at(0).unwrap();
193 assert_eq!(message.name(), "Engine");
194 assert_eq!(message.id(), 256);
195 }
196}