dbc_rs/dbc/builder/
build.rs1use super::DbcBuilder;
2use crate::{
3 Dbc, ExtendedMultiplexing, MAX_EXTENDED_MULTIPLEXING, Message, Nodes, Result, Version,
4 dbc::{Messages, Validate},
5};
6use std::collections::BTreeMap;
7
8impl DbcBuilder {
9 #[must_use = "validation result should be checked"]
26 pub fn validate(self) -> Result<()> {
27 let (_version, nodes, messages, value_descriptions) = {
31 let version = self.version.build()?;
32 let nodes = self.nodes.build()?;
33 let messages: std::vec::Vec<Message> = self
34 .messages
35 .into_iter()
36 .map(|builder| builder.build())
37 .collect::<Result<std::vec::Vec<_>>>()?;
38 let mut value_descriptions_map: BTreeMap<
39 (Option<u32>, String),
40 crate::value_descriptions::ValueDescriptions,
41 > = BTreeMap::new();
42 for ((message_id, signal_name), vd_builder) in self.value_descriptions {
43 let vd: crate::value_descriptions::ValueDescriptions = vd_builder.build()?;
44 value_descriptions_map.insert((message_id, signal_name), vd);
45 }
46 let value_descriptions =
47 crate::dbc::ValueDescriptionsMap::from_map(value_descriptions_map);
48 (version, nodes, messages, value_descriptions)
49 };
50
51 Validate::validate(&nodes, &messages, Some(&value_descriptions))?;
53
54 Ok(())
55 }
56
57 fn extract_fields(
58 self,
59 ) -> Result<(Version, Nodes, Messages, crate::dbc::ValueDescriptionsMap)> {
60 let version = self.version.build()?;
62
63 let nodes = self.nodes.build()?;
65
66 let messages_vec: std::vec::Vec<Message> = self
69 .messages
70 .into_iter()
71 .map(|builder| builder.build())
72 .collect::<Result<std::vec::Vec<_>>>()?;
73 let messages = Messages::new(&messages_vec)?;
74
75 let mut value_descriptions_map: BTreeMap<
77 (Option<u32>, String),
78 crate::value_descriptions::ValueDescriptions,
79 > = BTreeMap::new();
80 for ((message_id, signal_name), vd_builder) in self.value_descriptions {
81 let vd: crate::value_descriptions::ValueDescriptions = vd_builder.build()?;
82 value_descriptions_map.insert((message_id, signal_name), vd);
83 }
84 let value_descriptions = crate::dbc::ValueDescriptionsMap::from_map(value_descriptions_map);
85
86 Ok((version, nodes, messages, value_descriptions))
87 }
88
89 pub fn build(self) -> Result<Dbc> {
106 let (version, nodes, messages, value_descriptions) = self.extract_fields()?;
107 let messages_slice: std::vec::Vec<Message> = messages.iter().cloned().collect();
110 Validate::validate(&nodes, &messages_slice, Some(&value_descriptions))?;
111 let extended_multiplexing: crate::compat::Vec<
113 ExtendedMultiplexing,
114 { MAX_EXTENDED_MULTIPLEXING },
115 > = crate::compat::Vec::new();
116 Ok(Dbc::new(
117 Some(version),
118 nodes,
119 messages,
120 value_descriptions,
121 extended_multiplexing,
122 ))
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 #![allow(clippy::float_cmp)]
129 use super::DbcBuilder;
130 use crate::{
131 ByteOrder, MessageBuilder, NodesBuilder, ReceiversBuilder, SignalBuilder, VersionBuilder,
132 };
133
134 #[test]
135 fn test_dbc_builder_valid() {
136 let version = VersionBuilder::new().version("1.0");
137 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
138 let signal = SignalBuilder::new()
139 .name("RPM")
140 .start_bit(0)
141 .length(16)
142 .byte_order(ByteOrder::BigEndian)
143 .unsigned(true)
144 .factor(1.0)
145 .offset(0.0)
146 .min(0.0)
147 .max(100.0)
148 .receivers(ReceiversBuilder::new().none());
149 let message = MessageBuilder::new()
150 .id(256)
151 .name("EngineData")
152 .dlc(8)
153 .sender("ECM")
154 .add_signal(signal);
155
156 let dbc = DbcBuilder::new()
157 .version(version)
158 .nodes(nodes)
159 .add_message(message)
160 .build()
161 .unwrap();
162
163 assert_eq!(dbc.messages().len(), 1);
164 assert_eq!(dbc.messages().at(0).unwrap().id(), 256);
165 }
166
167 #[test]
168 fn test_dbc_builder_missing_version() {
169 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
170 let signal = SignalBuilder::new()
171 .name("RPM")
172 .start_bit(0)
173 .length(16)
174 .byte_order(ByteOrder::BigEndian)
175 .unsigned(true)
176 .factor(1.0)
177 .offset(0.0)
178 .min(0.0)
179 .max(100.0)
180 .receivers(ReceiversBuilder::new().none());
181 let message = MessageBuilder::new()
182 .id(256)
183 .name("EngineData")
184 .dlc(8)
185 .sender("ECM")
186 .add_signal(signal);
187
188 let result = DbcBuilder::new().nodes(nodes).add_message(message).build();
189 assert!(result.is_ok());
191 let dbc = result.unwrap();
192 assert_eq!(dbc.version().unwrap().as_str(), "");
193 }
194
195 #[test]
196 fn test_dbc_builder_missing_nodes() {
197 let version = VersionBuilder::new().version("1.0");
200 let signal = SignalBuilder::new()
201 .name("RPM")
202 .start_bit(0)
203 .length(16)
204 .byte_order(ByteOrder::BigEndian)
205 .unsigned(true)
206 .factor(1.0)
207 .offset(0.0)
208 .min(0.0)
209 .max(100.0)
210 .receivers(ReceiversBuilder::new().none());
211 let message = MessageBuilder::new()
212 .id(256)
213 .name("EngineData")
214 .dlc(8)
215 .sender("ECM")
216 .add_signal(signal);
217
218 let result = DbcBuilder::new().version(version).add_message(message).build();
220 assert!(result.is_ok());
221 let dbc = result.unwrap();
222 assert!(dbc.nodes().is_empty());
223 }
224
225 #[test]
226 fn test_dbc_builder_validate_missing_version() {
227 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
228 let result = DbcBuilder::new().nodes(nodes).validate();
230 assert!(result.is_ok());
231 }
232
233 #[test]
234 fn test_dbc_builder_validate_missing_nodes() {
235 let version = VersionBuilder::new().version("1.0");
237 let result = DbcBuilder::new().version(version).validate();
238 assert!(result.is_ok());
240 }
241
242 #[test]
243 fn test_dbc_builder_validate_valid() {
244 let version = VersionBuilder::new().version("1.0");
245 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
246 let signal = SignalBuilder::new()
247 .name("RPM")
248 .start_bit(0)
249 .length(16)
250 .byte_order(ByteOrder::BigEndian)
251 .unsigned(true)
252 .factor(1.0)
253 .offset(0.0)
254 .min(0.0)
255 .max(100.0)
256 .receivers(ReceiversBuilder::new().none());
257 let message = MessageBuilder::new()
258 .id(256)
259 .name("EngineData")
260 .dlc(8)
261 .sender("ECM")
262 .add_signal(signal);
263
264 let builder = DbcBuilder::new().version(version).nodes(nodes).add_message(message);
267 let result = builder.validate();
268 assert!(result.is_ok());
269 }
270}