1use super::DbcBuilder;
2use crate::{
3 Dbc, ExtendedMultiplexing, MAX_EXTENDED_MULTIPLEXING, MAX_MESSAGES, MAX_NAME_SIZE, Message,
4 Nodes, Result, Version,
5 compat::{BTreeMap, String, Vec as CompatVec},
6 dbc::{Messages, Validate},
7};
8
9impl DbcBuilder {
10 #[must_use = "validation result should be checked"]
27 pub fn validate(self) -> Result<()> {
28 let (_version, nodes, messages, value_descriptions, extended_multiplexing) = {
32 let version = self.version.build()?;
33 let nodes = self.nodes.build()?;
34 let messages: std::vec::Vec<Message> = self
35 .messages
36 .into_iter()
37 .map(|builder| builder.build())
38 .collect::<Result<std::vec::Vec<_>>>()?;
39 let mut value_descriptions_map: BTreeMap<
40 (Option<u32>, String<{ MAX_NAME_SIZE }>),
41 crate::value_descriptions::ValueDescriptions,
42 { MAX_MESSAGES },
43 > = BTreeMap::new();
44 for ((message_id, signal_name), vd_builder) in self.value_descriptions {
45 let vd: crate::value_descriptions::ValueDescriptions = vd_builder.build()?;
46 let compat_signal_name = String::try_from(signal_name.as_str())
47 .map_err(|_| crate::Error::Validation(crate::Error::MAX_NAME_SIZE_EXCEEDED))?;
48 let _ = value_descriptions_map.insert((message_id, compat_signal_name), vd);
49 }
50 let value_descriptions = crate::dbc::ValueDescriptionsMap::new(value_descriptions_map);
51
52 let extended_multiplexing_vec: std::vec::Vec<ExtendedMultiplexing> = self
54 .extended_multiplexing
55 .into_iter()
56 .map(|builder| builder.build())
57 .collect::<Result<std::vec::Vec<_>>>()?;
58
59 (
60 version,
61 nodes,
62 messages,
63 value_descriptions,
64 extended_multiplexing_vec,
65 )
66 };
67
68 Validate::validate(
70 &nodes,
71 &messages,
72 Some(&value_descriptions),
73 Some(&extended_multiplexing),
74 )?;
75
76 Ok(())
77 }
78
79 #[allow(clippy::type_complexity)]
80 fn extract_fields(
81 self,
82 ) -> Result<(
83 Version,
84 Nodes,
85 Messages,
86 crate::dbc::ValueDescriptionsMap,
87 CompatVec<ExtendedMultiplexing, { MAX_EXTENDED_MULTIPLEXING }>,
88 Option<std::string::String>,
89 )> {
90 let version = self.version.build()?;
92
93 let nodes = self.nodes.build()?;
95
96 let messages_vec: std::vec::Vec<Message> = self
99 .messages
100 .into_iter()
101 .map(|builder| builder.build())
102 .collect::<Result<std::vec::Vec<_>>>()?;
103 let messages = Messages::new(&messages_vec)?;
104
105 let mut value_descriptions_map: BTreeMap<
107 (Option<u32>, String<{ MAX_NAME_SIZE }>),
108 crate::value_descriptions::ValueDescriptions,
109 { MAX_MESSAGES },
110 > = BTreeMap::new();
111 for ((message_id, signal_name), vd_builder) in self.value_descriptions {
112 let vd: crate::value_descriptions::ValueDescriptions = vd_builder.build()?;
113 let compat_signal_name = String::try_from(signal_name.as_str())
114 .map_err(|_| crate::Error::Validation(crate::Error::MAX_NAME_SIZE_EXCEEDED))?;
115 let _ = value_descriptions_map.insert((message_id, compat_signal_name), vd);
116 }
117 let value_descriptions = crate::dbc::ValueDescriptionsMap::new(value_descriptions_map);
118
119 let extended_multiplexing_vec: std::vec::Vec<ExtendedMultiplexing> = self
121 .extended_multiplexing
122 .into_iter()
123 .map(|builder| builder.build())
124 .collect::<Result<std::vec::Vec<_>>>()?;
125
126 let mut extended_multiplexing: CompatVec<
128 ExtendedMultiplexing,
129 { MAX_EXTENDED_MULTIPLEXING },
130 > = CompatVec::new();
131 for ext_mux in extended_multiplexing_vec {
132 extended_multiplexing
133 .push(ext_mux)
134 .map_err(|_| crate::Error::expected("too many extended multiplexing entries"))?;
135 }
136
137 Ok((
138 version,
139 nodes,
140 messages,
141 value_descriptions,
142 extended_multiplexing,
143 self.comment,
144 ))
145 }
146
147 pub fn build(self) -> Result<Dbc> {
164 let (version, nodes, messages, value_descriptions, extended_multiplexing, comment) =
165 self.extract_fields()?;
166 let messages_slice: std::vec::Vec<Message> = messages.iter().cloned().collect();
169 let extended_multiplexing_slice: std::vec::Vec<ExtendedMultiplexing> =
170 extended_multiplexing.iter().cloned().collect();
171 Validate::validate(
172 &nodes,
173 &messages_slice,
174 Some(&value_descriptions),
175 Some(&extended_multiplexing_slice),
176 )?;
177 Ok(Dbc::new(
178 Some(version),
179 nodes,
180 messages,
181 value_descriptions,
182 extended_multiplexing,
183 comment.map(|c| c.into()),
184 ))
185 }
186}
187
188#[cfg(test)]
189mod tests {
190 #![allow(clippy::float_cmp)]
191 use super::DbcBuilder;
192 use crate::{
193 ByteOrder, ExtendedMultiplexingBuilder, MessageBuilder, NodesBuilder, ReceiversBuilder,
194 SignalBuilder, ValueDescriptionsBuilder, VersionBuilder,
195 };
196
197 #[test]
198 fn test_dbc_builder_valid() {
199 let version = VersionBuilder::new().version("1.0");
200 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
201 let signal = SignalBuilder::new()
202 .name("RPM")
203 .start_bit(0)
204 .length(16)
205 .byte_order(ByteOrder::BigEndian)
206 .unsigned(true)
207 .factor(1.0)
208 .offset(0.0)
209 .min(0.0)
210 .max(100.0)
211 .receivers(ReceiversBuilder::new().none());
212 let message = MessageBuilder::new()
213 .id(256)
214 .name("EngineData")
215 .dlc(8)
216 .sender("ECM")
217 .add_signal(signal);
218
219 let dbc = DbcBuilder::new()
220 .version(version)
221 .nodes(nodes)
222 .add_message(message)
223 .build()
224 .unwrap();
225
226 assert_eq!(dbc.messages().len(), 1);
227 assert_eq!(dbc.messages().at(0).unwrap().id(), 256);
228 }
229
230 #[test]
231 fn test_dbc_builder_missing_version() {
232 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
233 let signal = SignalBuilder::new()
234 .name("RPM")
235 .start_bit(0)
236 .length(16)
237 .byte_order(ByteOrder::BigEndian)
238 .unsigned(true)
239 .factor(1.0)
240 .offset(0.0)
241 .min(0.0)
242 .max(100.0)
243 .receivers(ReceiversBuilder::new().none());
244 let message = MessageBuilder::new()
245 .id(256)
246 .name("EngineData")
247 .dlc(8)
248 .sender("ECM")
249 .add_signal(signal);
250
251 let result = DbcBuilder::new().nodes(nodes).add_message(message).build();
252 assert!(result.is_ok());
254 let dbc = result.unwrap();
255 assert_eq!(dbc.version().unwrap().as_str(), "");
256 }
257
258 #[test]
259 fn test_dbc_builder_missing_nodes() {
260 let version = VersionBuilder::new().version("1.0");
263 let signal = SignalBuilder::new()
264 .name("RPM")
265 .start_bit(0)
266 .length(16)
267 .byte_order(ByteOrder::BigEndian)
268 .unsigned(true)
269 .factor(1.0)
270 .offset(0.0)
271 .min(0.0)
272 .max(100.0)
273 .receivers(ReceiversBuilder::new().none());
274 let message = MessageBuilder::new()
275 .id(256)
276 .name("EngineData")
277 .dlc(8)
278 .sender("ECM")
279 .add_signal(signal);
280
281 let result = DbcBuilder::new().version(version).add_message(message).build();
283 assert!(result.is_ok());
284 let dbc = result.unwrap();
285 assert!(dbc.nodes().is_empty());
286 }
287
288 #[test]
289 fn test_dbc_builder_validate_missing_version() {
290 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
291 let result = DbcBuilder::new().nodes(nodes).validate();
293 assert!(result.is_ok());
294 }
295
296 #[test]
297 fn test_dbc_builder_validate_missing_nodes() {
298 let version = VersionBuilder::new().version("1.0");
300 let result = DbcBuilder::new().version(version).validate();
301 assert!(result.is_ok());
303 }
304
305 #[test]
306 fn test_dbc_builder_validate_valid() {
307 let version = VersionBuilder::new().version("1.0");
308 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
309 let signal = SignalBuilder::new()
310 .name("RPM")
311 .start_bit(0)
312 .length(16)
313 .byte_order(ByteOrder::BigEndian)
314 .unsigned(true)
315 .factor(1.0)
316 .offset(0.0)
317 .min(0.0)
318 .max(100.0)
319 .receivers(ReceiversBuilder::new().none());
320 let message = MessageBuilder::new()
321 .id(256)
322 .name("EngineData")
323 .dlc(8)
324 .sender("ECM")
325 .add_signal(signal);
326
327 let builder = DbcBuilder::new().version(version).nodes(nodes).add_message(message);
330 let result = builder.validate();
331 assert!(result.is_ok());
332 }
333
334 #[test]
339 fn test_dbc_builder_with_value_descriptions() {
340 let version = VersionBuilder::new().version("1.0");
341 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
342 let signal = SignalBuilder::new()
343 .name("Gear")
344 .start_bit(0)
345 .length(8)
346 .byte_order(ByteOrder::LittleEndian)
347 .unsigned(true)
348 .factor(1.0)
349 .offset(0.0)
350 .min(0.0)
351 .max(5.0)
352 .receivers(ReceiversBuilder::new().none());
353 let message = MessageBuilder::new()
354 .id(256)
355 .name("Transmission")
356 .dlc(8)
357 .sender("ECM")
358 .add_signal(signal);
359
360 let value_desc = ValueDescriptionsBuilder::new()
361 .add_entry(0, "Park")
362 .add_entry(1, "Reverse")
363 .add_entry(2, "Neutral")
364 .add_entry(3, "Drive");
365
366 let dbc = DbcBuilder::new()
367 .version(version)
368 .nodes(nodes)
369 .add_message(message)
370 .add_value_description(256, "Gear", value_desc)
371 .build()
372 .unwrap();
373
374 let vd = dbc.value_descriptions_for_signal(256, "Gear").unwrap();
376 assert_eq!(vd.get(0), Some("Park"));
377 assert_eq!(vd.get(1), Some("Reverse"));
378 assert_eq!(vd.get(2), Some("Neutral"));
379 assert_eq!(vd.get(3), Some("Drive"));
380 }
381
382 #[test]
383 fn test_dbc_builder_value_descriptions_message_not_found() {
384 let version = VersionBuilder::new().version("1.0");
385 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
386 let signal = SignalBuilder::new()
387 .name("RPM")
388 .start_bit(0)
389 .length(16)
390 .byte_order(ByteOrder::BigEndian)
391 .unsigned(true)
392 .factor(1.0)
393 .offset(0.0)
394 .min(0.0)
395 .max(100.0)
396 .receivers(ReceiversBuilder::new().none());
397 let message = MessageBuilder::new()
398 .id(256)
399 .name("EngineData")
400 .dlc(8)
401 .sender("ECM")
402 .add_signal(signal);
403
404 let value_desc = ValueDescriptionsBuilder::new().add_entry(0, "Off").add_entry(1, "On");
406
407 let result = DbcBuilder::new()
408 .version(version)
409 .nodes(nodes)
410 .add_message(message)
411 .add_value_description(999, "RPM", value_desc) .build();
413
414 assert!(result.is_err());
415 }
416
417 #[test]
418 fn test_dbc_builder_value_descriptions_signal_not_found() {
419 let version = VersionBuilder::new().version("1.0");
420 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
421 let signal = SignalBuilder::new()
422 .name("RPM")
423 .start_bit(0)
424 .length(16)
425 .byte_order(ByteOrder::BigEndian)
426 .unsigned(true)
427 .factor(1.0)
428 .offset(0.0)
429 .min(0.0)
430 .max(100.0)
431 .receivers(ReceiversBuilder::new().none());
432 let message = MessageBuilder::new()
433 .id(256)
434 .name("EngineData")
435 .dlc(8)
436 .sender("ECM")
437 .add_signal(signal);
438
439 let value_desc = ValueDescriptionsBuilder::new().add_entry(0, "Off").add_entry(1, "On");
441
442 let result = DbcBuilder::new()
443 .version(version)
444 .nodes(nodes)
445 .add_message(message)
446 .add_value_description(256, "NonExistentSignal", value_desc)
447 .build();
448
449 assert!(result.is_err());
450 }
451
452 #[test]
453 fn test_dbc_builder_validate_with_value_descriptions() {
454 let version = VersionBuilder::new().version("1.0");
455 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
456 let signal = SignalBuilder::new()
457 .name("Gear")
458 .start_bit(0)
459 .length(8)
460 .byte_order(ByteOrder::LittleEndian)
461 .unsigned(true)
462 .factor(1.0)
463 .offset(0.0)
464 .min(0.0)
465 .max(5.0)
466 .receivers(ReceiversBuilder::new().none());
467 let message = MessageBuilder::new()
468 .id(256)
469 .name("Transmission")
470 .dlc(8)
471 .sender("ECM")
472 .add_signal(signal);
473
474 let value_desc = ValueDescriptionsBuilder::new().add_entry(0, "Park").add_entry(1, "Drive");
475
476 let result = DbcBuilder::new()
477 .version(version)
478 .nodes(nodes)
479 .add_message(message)
480 .add_value_description(256, "Gear", value_desc)
481 .validate();
482
483 assert!(result.is_ok());
484 }
485
486 #[test]
491 fn test_dbc_builder_with_extended_multiplexing() {
492 let version = VersionBuilder::new().version("1.0");
493 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
494
495 let mux_signal = SignalBuilder::new()
497 .name("Mux1")
498 .start_bit(0)
499 .length(8)
500 .byte_order(ByteOrder::LittleEndian)
501 .unsigned(true)
502 .factor(1.0)
503 .offset(0.0)
504 .min(0.0)
505 .max(255.0)
506 .receivers(ReceiversBuilder::new().none());
507
508 let signal_a = SignalBuilder::new()
510 .name("SignalA")
511 .start_bit(16)
512 .length(16)
513 .byte_order(ByteOrder::LittleEndian)
514 .unsigned(true)
515 .factor(0.1)
516 .offset(0.0)
517 .min(0.0)
518 .max(100.0)
519 .receivers(ReceiversBuilder::new().none());
520
521 let message = MessageBuilder::new()
522 .id(500)
523 .name("MuxMessage")
524 .dlc(8)
525 .sender("ECM")
526 .add_signal(mux_signal)
527 .add_signal(signal_a);
528
529 let ext_mux = ExtendedMultiplexingBuilder::new()
531 .message_id(500)
532 .signal_name("SignalA")
533 .multiplexer_switch("Mux1")
534 .add_value_range(0, 5)
535 .add_value_range(10, 15);
536
537 let dbc = DbcBuilder::new()
538 .version(version)
539 .nodes(nodes)
540 .add_message(message)
541 .add_extended_multiplexing(ext_mux)
542 .build()
543 .unwrap();
544
545 assert_eq!(dbc.messages().len(), 1);
546 assert_eq!(dbc.extended_multiplexing().len(), 1);
547
548 let ext_mux = &dbc.extended_multiplexing()[0];
549 assert_eq!(ext_mux.message_id(), 500);
550 assert_eq!(ext_mux.signal_name(), "SignalA");
551 assert_eq!(ext_mux.multiplexer_switch(), "Mux1");
552 assert_eq!(ext_mux.value_ranges().len(), 2);
553 assert_eq!(ext_mux.value_ranges()[0], (0, 5));
554 assert_eq!(ext_mux.value_ranges()[1], (10, 15));
555 }
556
557 #[test]
558 fn test_dbc_builder_extended_multiplexing_message_not_found() {
559 let version = VersionBuilder::new().version("1.0");
560 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
561
562 let signal = SignalBuilder::new()
563 .name("RPM")
564 .start_bit(0)
565 .length(16)
566 .byte_order(ByteOrder::BigEndian)
567 .unsigned(true)
568 .factor(1.0)
569 .offset(0.0)
570 .min(0.0)
571 .max(100.0)
572 .receivers(ReceiversBuilder::new().none());
573
574 let message = MessageBuilder::new()
575 .id(256)
576 .name("EngineData")
577 .dlc(8)
578 .sender("ECM")
579 .add_signal(signal);
580
581 let ext_mux = ExtendedMultiplexingBuilder::new()
583 .message_id(999) .signal_name("RPM")
585 .multiplexer_switch("Mux1")
586 .add_value_range(0, 5);
587
588 let result = DbcBuilder::new()
589 .version(version)
590 .nodes(nodes)
591 .add_message(message)
592 .add_extended_multiplexing(ext_mux)
593 .build();
594
595 assert!(result.is_err());
596 }
597
598 #[test]
599 fn test_dbc_builder_extended_multiplexing_signal_not_found() {
600 let version = VersionBuilder::new().version("1.0");
601 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
602
603 let mux_signal = SignalBuilder::new()
604 .name("Mux1")
605 .start_bit(0)
606 .length(8)
607 .byte_order(ByteOrder::BigEndian)
608 .unsigned(true)
609 .factor(1.0)
610 .offset(0.0)
611 .min(0.0)
612 .max(100.0)
613 .receivers(ReceiversBuilder::new().none());
614
615 let message = MessageBuilder::new()
616 .id(256)
617 .name("EngineData")
618 .dlc(8)
619 .sender("ECM")
620 .add_signal(mux_signal);
621
622 let ext_mux = ExtendedMultiplexingBuilder::new()
624 .message_id(256)
625 .signal_name("NonExistent") .multiplexer_switch("Mux1")
627 .add_value_range(0, 5);
628
629 let result = DbcBuilder::new()
630 .version(version)
631 .nodes(nodes)
632 .add_message(message)
633 .add_extended_multiplexing(ext_mux)
634 .build();
635
636 assert!(result.is_err());
637 }
638
639 #[test]
640 fn test_dbc_builder_extended_multiplexing_switch_not_found() {
641 let version = VersionBuilder::new().version("1.0");
642 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
643
644 let signal = SignalBuilder::new()
645 .name("SignalA")
646 .start_bit(0)
647 .length(16)
648 .byte_order(ByteOrder::BigEndian)
649 .unsigned(true)
650 .factor(1.0)
651 .offset(0.0)
652 .min(0.0)
653 .max(100.0)
654 .receivers(ReceiversBuilder::new().none());
655
656 let message = MessageBuilder::new()
657 .id(256)
658 .name("EngineData")
659 .dlc(8)
660 .sender("ECM")
661 .add_signal(signal);
662
663 let ext_mux = ExtendedMultiplexingBuilder::new()
665 .message_id(256)
666 .signal_name("SignalA")
667 .multiplexer_switch("NonExistentMux") .add_value_range(0, 5);
669
670 let result = DbcBuilder::new()
671 .version(version)
672 .nodes(nodes)
673 .add_message(message)
674 .add_extended_multiplexing(ext_mux)
675 .build();
676
677 assert!(result.is_err());
678 }
679
680 #[test]
681 fn test_dbc_builder_extended_multiplexing_invalid_range() {
682 let version = VersionBuilder::new().version("1.0");
683 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
684
685 let mux_signal = SignalBuilder::new()
686 .name("Mux1")
687 .start_bit(0)
688 .length(8)
689 .byte_order(ByteOrder::LittleEndian)
690 .unsigned(true)
691 .factor(1.0)
692 .offset(0.0)
693 .min(0.0)
694 .max(255.0)
695 .receivers(ReceiversBuilder::new().none());
696
697 let signal_a = SignalBuilder::new()
698 .name("SignalA")
699 .start_bit(16)
700 .length(16)
701 .byte_order(ByteOrder::LittleEndian)
702 .unsigned(true)
703 .factor(0.1)
704 .offset(0.0)
705 .min(0.0)
706 .max(100.0)
707 .receivers(ReceiversBuilder::new().none());
708
709 let message = MessageBuilder::new()
710 .id(500)
711 .name("MuxMessage")
712 .dlc(8)
713 .sender("ECM")
714 .add_signal(mux_signal)
715 .add_signal(signal_a);
716
717 let ext_mux = ExtendedMultiplexingBuilder::new()
719 .message_id(500)
720 .signal_name("SignalA")
721 .multiplexer_switch("Mux1")
722 .add_value_range(10, 5); let result = DbcBuilder::new()
725 .version(version)
726 .nodes(nodes)
727 .add_message(message)
728 .add_extended_multiplexing(ext_mux)
729 .build();
730
731 assert!(result.is_err());
732 }
733
734 #[test]
735 fn test_dbc_builder_validate_with_extended_multiplexing() {
736 let version = VersionBuilder::new().version("1.0");
737 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
738
739 let mux_signal = SignalBuilder::new()
740 .name("Mux1")
741 .start_bit(0)
742 .length(8)
743 .byte_order(ByteOrder::LittleEndian)
744 .unsigned(true)
745 .factor(1.0)
746 .offset(0.0)
747 .min(0.0)
748 .max(255.0)
749 .receivers(ReceiversBuilder::new().none());
750
751 let signal_a = SignalBuilder::new()
752 .name("SignalA")
753 .start_bit(16)
754 .length(16)
755 .byte_order(ByteOrder::LittleEndian)
756 .unsigned(true)
757 .factor(0.1)
758 .offset(0.0)
759 .min(0.0)
760 .max(100.0)
761 .receivers(ReceiversBuilder::new().none());
762
763 let message = MessageBuilder::new()
764 .id(500)
765 .name("MuxMessage")
766 .dlc(8)
767 .sender("ECM")
768 .add_signal(mux_signal)
769 .add_signal(signal_a);
770
771 let ext_mux = ExtendedMultiplexingBuilder::new()
772 .message_id(500)
773 .signal_name("SignalA")
774 .multiplexer_switch("Mux1")
775 .add_value_range(0, 5);
776
777 let result = DbcBuilder::new()
778 .version(version)
779 .nodes(nodes)
780 .add_message(message)
781 .add_extended_multiplexing(ext_mux)
782 .validate();
783
784 assert!(result.is_ok());
785 }
786
787 #[test]
788 fn test_dbc_builder_multiple_extended_multiplexing() {
789 let version = VersionBuilder::new().version("1.0");
790 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
791
792 let mux_signal = SignalBuilder::new()
793 .name("Mux1")
794 .start_bit(0)
795 .length(8)
796 .byte_order(ByteOrder::LittleEndian)
797 .unsigned(true)
798 .factor(1.0)
799 .offset(0.0)
800 .min(0.0)
801 .max(255.0)
802 .receivers(ReceiversBuilder::new().none());
803
804 let signal_a = SignalBuilder::new()
805 .name("SignalA")
806 .start_bit(16)
807 .length(8)
808 .byte_order(ByteOrder::LittleEndian)
809 .unsigned(true)
810 .factor(1.0)
811 .offset(0.0)
812 .min(0.0)
813 .max(255.0)
814 .receivers(ReceiversBuilder::new().none());
815
816 let signal_b = SignalBuilder::new()
817 .name("SignalB")
818 .start_bit(24)
819 .length(8)
820 .byte_order(ByteOrder::LittleEndian)
821 .unsigned(true)
822 .factor(1.0)
823 .offset(0.0)
824 .min(0.0)
825 .max(255.0)
826 .receivers(ReceiversBuilder::new().none());
827
828 let message = MessageBuilder::new()
829 .id(500)
830 .name("MuxMessage")
831 .dlc(8)
832 .sender("ECM")
833 .add_signal(mux_signal)
834 .add_signal(signal_a)
835 .add_signal(signal_b);
836
837 let ext_mux_a = ExtendedMultiplexingBuilder::new()
838 .message_id(500)
839 .signal_name("SignalA")
840 .multiplexer_switch("Mux1")
841 .add_value_range(0, 5);
842
843 let ext_mux_b = ExtendedMultiplexingBuilder::new()
844 .message_id(500)
845 .signal_name("SignalB")
846 .multiplexer_switch("Mux1")
847 .add_value_range(10, 15);
848
849 let dbc = DbcBuilder::new()
850 .version(version)
851 .nodes(nodes)
852 .add_message(message)
853 .add_extended_multiplexings(vec![ext_mux_a, ext_mux_b])
854 .build()
855 .unwrap();
856
857 assert_eq!(dbc.extended_multiplexing().len(), 2);
858 assert_eq!(dbc.extended_multiplexing()[0].signal_name(), "SignalA");
859 assert_eq!(dbc.extended_multiplexing()[1].signal_name(), "SignalB");
860 }
861
862 #[test]
863 fn test_dbc_builder_clear_extended_multiplexing() {
864 let version = VersionBuilder::new().version("1.0");
865 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
866
867 let mux_signal = SignalBuilder::new()
868 .name("Mux1")
869 .start_bit(0)
870 .length(8)
871 .byte_order(ByteOrder::LittleEndian)
872 .unsigned(true)
873 .factor(1.0)
874 .offset(0.0)
875 .min(0.0)
876 .max(255.0)
877 .receivers(ReceiversBuilder::new().none());
878
879 let signal_a = SignalBuilder::new()
880 .name("SignalA")
881 .start_bit(16)
882 .length(16)
883 .byte_order(ByteOrder::LittleEndian)
884 .unsigned(true)
885 .factor(0.1)
886 .offset(0.0)
887 .min(0.0)
888 .max(100.0)
889 .receivers(ReceiversBuilder::new().none());
890
891 let message = MessageBuilder::new()
892 .id(500)
893 .name("MuxMessage")
894 .dlc(8)
895 .sender("ECM")
896 .add_signal(mux_signal)
897 .add_signal(signal_a);
898
899 let ext_mux = ExtendedMultiplexingBuilder::new()
900 .message_id(500)
901 .signal_name("SignalA")
902 .multiplexer_switch("Mux1")
903 .add_value_range(0, 5);
904
905 let dbc = DbcBuilder::new()
906 .version(version)
907 .nodes(nodes)
908 .add_message(message)
909 .add_extended_multiplexing(ext_mux)
910 .clear_extended_multiplexing()
911 .build()
912 .unwrap();
913
914 assert_eq!(dbc.extended_multiplexing().len(), 0);
915 }
916
917 #[test]
922 fn test_dbc_builder_with_value_descriptions_and_extended_multiplexing() {
923 let version = VersionBuilder::new().version("1.0");
924 let nodes = NodesBuilder::new().add_nodes(["ECM"]);
925
926 let mux_signal = SignalBuilder::new()
927 .name("Mux1")
928 .start_bit(0)
929 .length(8)
930 .byte_order(ByteOrder::LittleEndian)
931 .unsigned(true)
932 .factor(1.0)
933 .offset(0.0)
934 .min(0.0)
935 .max(255.0)
936 .receivers(ReceiversBuilder::new().none());
937
938 let signal_a = SignalBuilder::new()
939 .name("SignalA")
940 .start_bit(16)
941 .length(8)
942 .byte_order(ByteOrder::LittleEndian)
943 .unsigned(true)
944 .factor(1.0)
945 .offset(0.0)
946 .min(0.0)
947 .max(3.0)
948 .receivers(ReceiversBuilder::new().none());
949
950 let message = MessageBuilder::new()
951 .id(500)
952 .name("MuxMessage")
953 .dlc(8)
954 .sender("ECM")
955 .add_signal(mux_signal)
956 .add_signal(signal_a);
957
958 let value_desc = ValueDescriptionsBuilder::new()
959 .add_entry(0, "Off")
960 .add_entry(1, "Low")
961 .add_entry(2, "Medium")
962 .add_entry(3, "High");
963
964 let ext_mux = ExtendedMultiplexingBuilder::new()
965 .message_id(500)
966 .signal_name("SignalA")
967 .multiplexer_switch("Mux1")
968 .add_value_range(0, 5);
969
970 let dbc = DbcBuilder::new()
971 .version(version)
972 .nodes(nodes)
973 .add_message(message)
974 .add_value_description(500, "SignalA", value_desc)
975 .add_extended_multiplexing(ext_mux)
976 .build()
977 .unwrap();
978
979 let vd = dbc.value_descriptions_for_signal(500, "SignalA").unwrap();
981 assert_eq!(vd.get(0), Some("Off"));
982 assert_eq!(vd.get(3), Some("High"));
983
984 assert_eq!(dbc.extended_multiplexing().len(), 1);
986 assert_eq!(dbc.extended_multiplexing()[0].signal_name(), "SignalA");
987 }
988}