dbc_rs/message/builder/
build.rs1use super::MessageBuilder;
2use crate::{
3 Error, MAX_NAME_SIZE, Message, Result, Signal, SignalBuilder, compat, message::Signals,
4 required_field,
5};
6
7impl MessageBuilder {
8 #[allow(clippy::type_complexity)]
9 fn extract_fields(
10 self,
11 ) -> Result<(u32, String, u8, String, Vec<SignalBuilder>, Option<String>)> {
12 let id = required_field!(self.id, Error::message(Error::MESSAGE_ID_REQUIRED))?;
13 let name = required_field!(self.name, Error::message(Error::MESSAGE_NAME_EMPTY))?;
14 let dlc = required_field!(self.dlc, Error::message(Error::MESSAGE_DLC_REQUIRED))?;
15 let sender = required_field!(self.sender, Error::message(Error::MESSAGE_SENDER_EMPTY))?;
16 Ok((id, name, dlc, sender, self.signals, self.comment))
17 }
18
19 pub fn validate(&self) -> Result<()> {
31 let id = required_field!(self.id, Error::message(Error::MESSAGE_ID_REQUIRED))?;
33 let name = required_field!(
34 self.name.as_ref(),
35 Error::message(Error::MESSAGE_NAME_EMPTY)
36 )?;
37 let dlc = required_field!(self.dlc, Error::message(Error::MESSAGE_DLC_REQUIRED))?;
38 let sender = required_field!(
39 self.sender.as_ref(),
40 Error::message(Error::MESSAGE_SENDER_EMPTY)
41 )?;
42
43 let built_signals: Vec<Signal> = self
45 .signals
46 .iter()
47 .cloned()
48 .map(|sig_builder| sig_builder.build())
49 .collect::<Result<Vec<_>>>()?;
50
51 Message::validate(id, name, dlc, sender, &built_signals)?;
53
54 Ok(())
55 }
56
57 pub fn build(self) -> Result<Message> {
99 let (id, name, dlc, sender, signals, comment) = self.extract_fields()?;
100 let built_signals: Vec<Signal> = signals
102 .into_iter()
103 .map(|sig_builder| sig_builder.build())
104 .collect::<Result<Vec<_>>>()?;
105 Message::validate(id, &name, dlc, &sender, &built_signals)?;
107
108 let name_str: compat::String<{ MAX_NAME_SIZE }> = compat::validate_name(&name)?;
110 let sender_str: compat::String<{ MAX_NAME_SIZE }> = compat::validate_name(&sender)?;
111 let signals_collection = Signals::from_slice(&built_signals);
112
113 Ok(Message::new(
114 id,
115 name_str,
116 dlc,
117 sender_str,
118 signals_collection,
119 comment.map(|c| c.into()),
120 ))
121 }
122}
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127 use crate::{ByteOrder, ReceiversBuilder};
128
129 fn minimal_signal() -> SignalBuilder {
130 SignalBuilder::new()
131 .name("TestSignal")
132 .start_bit(0)
133 .length(8)
134 .byte_order(ByteOrder::LittleEndian)
135 .unsigned(true)
136 .factor(1.0)
137 .offset(0.0)
138 .min(0.0)
139 .max(255.0)
140 .receivers(ReceiversBuilder::new().none())
141 }
142
143 fn minimal_message() -> MessageBuilder {
144 MessageBuilder::new().id(256).name("TestMessage").dlc(8).sender("ECM")
145 }
146
147 #[test]
148 fn test_message_builder_new() {
149 let builder = MessageBuilder::new();
150 assert!(builder.build().is_err());
152 }
153
154 #[test]
155 fn test_message_builder_default() {
156 let builder = MessageBuilder::default();
157 assert!(builder.build().is_err());
158 }
159
160 #[test]
161 fn test_message_builder_minimal() {
162 let message = minimal_message().build().unwrap();
163
164 assert_eq!(message.id(), 256);
165 assert_eq!(message.name(), "TestMessage");
166 assert_eq!(message.dlc(), 8);
167 assert_eq!(message.sender(), "ECM");
168 assert_eq!(message.signals().len(), 0);
169 }
170
171 #[test]
172 fn test_message_builder_missing_id() {
173 let result = MessageBuilder::new().name("Test").dlc(8).sender("ECM").build();
174
175 assert!(result.is_err());
176 }
177
178 #[test]
179 fn test_message_builder_missing_name() {
180 let result = MessageBuilder::new().id(256).dlc(8).sender("ECM").build();
181
182 assert!(result.is_err());
183 }
184
185 #[test]
186 fn test_message_builder_missing_dlc() {
187 let result = MessageBuilder::new().id(256).name("Test").sender("ECM").build();
188
189 assert!(result.is_err());
190 }
191
192 #[test]
193 fn test_message_builder_missing_sender() {
194 let result = MessageBuilder::new().id(256).name("Test").dlc(8).build();
195
196 assert!(result.is_err());
197 }
198
199 #[test]
200 fn test_message_builder_validate_valid() {
201 let builder = minimal_message().add_signal(minimal_signal());
202 let result = builder.validate();
203 assert!(result.is_ok());
204 }
205
206 #[test]
207 fn test_message_builder_validate_missing_id() {
208 let builder = MessageBuilder::new().name("Test").dlc(8).sender("ECM");
209 let result = builder.validate();
210 assert!(result.is_err());
211 }
212
213 #[test]
214 fn test_message_builder_validate_missing_name() {
215 let builder = MessageBuilder::new().id(256).dlc(8).sender("ECM");
216 let result = builder.validate();
217 assert!(result.is_err());
218 }
219
220 #[test]
221 fn test_message_builder_validate_missing_dlc() {
222 let builder = MessageBuilder::new().id(256).name("Test").sender("ECM");
223 let result = builder.validate();
224 assert!(result.is_err());
225 }
226
227 #[test]
228 fn test_message_builder_validate_missing_sender() {
229 let builder = MessageBuilder::new().id(256).name("Test").dlc(8);
230 let result = builder.validate();
231 assert!(result.is_err());
232 }
233
234 #[test]
235 fn test_message_builder_extended_id() {
236 let message = MessageBuilder::new()
238 .id(0x80000100) .name("ExtendedMsg")
240 .dlc(8)
241 .sender("ECM")
242 .build()
243 .unwrap();
244
245 assert_eq!(message.id(), 0x100);
247 assert!(message.is_extended());
248 }
249
250 #[test]
251 fn test_message_builder_dlc_zero() {
252 let message = minimal_message().dlc(0).build().unwrap();
253 assert_eq!(message.dlc(), 0);
254 }
255
256 #[test]
257 fn test_message_builder_dlc_max() {
258 let message = minimal_message().dlc(64).build().unwrap();
260 assert_eq!(message.dlc(), 64);
261 }
262
263 #[test]
264 fn test_message_builder_with_comment() {
265 let message = minimal_message()
266 .comment("Engine status message with RPM and temperature")
267 .build()
268 .unwrap();
269
270 assert_eq!(
271 message.comment(),
272 Some("Engine status message with RPM and temperature")
273 );
274 }
275
276 #[test]
277 fn test_message_builder_without_comment() {
278 let message = minimal_message().build().unwrap();
279 assert_eq!(message.comment(), None);
280 }
281}