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