1use crate::{Dbc, Error, MAX_EXTENDED_MULTIPLEXING, MAX_SIGNALS_PER_MESSAGE, Result, compat::Vec};
2
3impl Dbc {
5 #[inline]
51 pub fn decode(
52 &self,
53 id: u32,
54 payload: &[u8],
55 ) -> Result<Vec<(&str, f64, Option<&str>), { MAX_SIGNALS_PER_MESSAGE }>> {
56 let message = self
59 .messages()
60 .find_by_id(id)
61 .ok_or(Error::Decoding(Error::MESSAGE_NOT_FOUND))?;
62
63 let dlc = message.dlc() as usize;
65
66 if payload.len() < dlc {
68 return Err(Error::Decoding(Error::PAYLOAD_LENGTH_MISMATCH));
69 }
70
71 let mut decoded_signals: Vec<(&str, f64, Option<&str>), { MAX_SIGNALS_PER_MESSAGE }> =
74 Vec::new();
75
76 let signals = message.signals();
77
78 let mut switch_values: Vec<(&str, u64), 16> = Vec::new();
81 for signal in signals.iter() {
82 if signal.is_multiplexer_switch() {
83 let value = signal.decode(payload)?;
84 let raw_value = {
87 let start_bit = signal.start_bit() as usize;
88 let length = signal.length() as usize;
89 let raw_bits = signal.byte_order().extract_bits(payload, start_bit, length);
90 if signal.is_unsigned() {
91 raw_bits as i64
92 } else {
93 let sign_bit_mask = 1u64 << (length - 1);
94 if (raw_bits & sign_bit_mask) != 0 {
95 let mask = !((1u64 << length) - 1);
96 (raw_bits | mask) as i64
97 } else {
98 raw_bits as i64
99 }
100 }
101 };
102 if raw_value < 0 {
105 return Err(Error::Decoding(Error::MULTIPLEXER_SWITCH_NEGATIVE));
106 }
107 switch_values
108 .push((signal.name(), raw_value as u64))
109 .map_err(|_| Error::Decoding(Error::MESSAGE_TOO_MANY_SIGNALS))?;
110 decoded_signals
112 .push((signal.name(), value, signal.unit()))
113 .map_err(|_| Error::Decoding(Error::MESSAGE_TOO_MANY_SIGNALS))?;
114 }
115 }
116
117 let extended_mux_entries = self.extended_multiplexing_for_message(id);
119
120 for signal in signals.iter() {
122 if signal.is_multiplexer_switch() {
124 continue;
125 }
126
127 let should_decode = if let Some(mux_value) = signal.multiplexer_switch_value() {
129 let extended_entries_for_signal: Vec<_, { MAX_EXTENDED_MULTIPLEXING }> =
133 extended_mux_entries
134 .iter()
135 .filter(|ext_mux| ext_mux.signal_name() == signal.name())
136 .cloned()
137 .collect();
138
139 if !extended_entries_for_signal.is_empty() {
140 let mut unique_switches: Vec<&str, 16> = Vec::new();
143 for ext_mux in extended_entries_for_signal.iter() {
144 let switch_name = ext_mux.multiplexer_switch();
145 if !unique_switches.iter().any(|&s| s == switch_name) {
146 unique_switches
147 .push(switch_name)
148 .map_err(|_| Error::Decoding(Error::MESSAGE_TOO_MANY_SIGNALS))?;
149 }
150 }
151
152 unique_switches.iter().all(|switch_name| {
154 let switch_val = switch_values
156 .iter()
157 .find(|(name, _)| *name == *switch_name)
158 .map(|(_, val)| *val);
159
160 if let Some(val) = switch_val {
161 extended_entries_for_signal
163 .iter()
164 .filter(|e| e.multiplexer_switch() == *switch_name)
165 .any(|ext_mux| {
166 ext_mux
167 .value_ranges()
168 .iter()
169 .any(|(min, max)| val >= *min && val <= *max)
170 })
171 } else {
172 false
174 }
175 })
176 } else {
177 switch_values.iter().any(|(_, switch_val)| *switch_val == mux_value)
180 }
181 } else {
182 true
184 };
185
186 if should_decode {
187 let value = signal.decode(payload)?;
188 decoded_signals
189 .push((signal.name(), value, signal.unit()))
190 .map_err(|_| Error::Decoding(Error::MESSAGE_TOO_MANY_SIGNALS))?;
191 }
192 }
193
194 Ok(decoded_signals)
195 }
196}
197
198#[cfg(test)]
199mod tests {
200 use crate::Dbc;
201
202 #[test]
203 fn test_decode_basic() {
204 let dbc = Dbc::parse(
205 r#"VERSION "1.0"
206
207BU_: ECM
208
209BO_ 256 Engine : 8 ECM
210 SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm" *
211"#,
212 )
213 .unwrap();
214
215 let payload = [0x40, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
217 let decoded = dbc.decode(256, &payload).unwrap();
218 assert_eq!(decoded.len(), 1);
219 assert_eq!(decoded[0].0, "RPM");
220 assert_eq!(decoded[0].1, 2000.0);
221 assert_eq!(decoded[0].2, Some("rpm"));
222 }
223
224 #[test]
225 fn test_decode_message_not_found() {
226 let dbc = Dbc::parse(
227 r#"VERSION "1.0"
228
229BU_: ECM
230
231BO_ 256 Engine : 8 ECM
232"#,
233 )
234 .unwrap();
235
236 let payload = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
237 let result = dbc.decode(512, &payload);
238 assert!(result.is_err());
239 }
240
241 #[test]
242 fn test_decode_message() {
243 let data = r#"VERSION "1.0"
244
245BU_: ECM
246
247BO_ 256 Engine : 8 ECM
248 SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm" *
249 SG_ Temp : 16|8@1- (1,-40) [-40|215] "°C" *
250"#;
251
252 let dbc = Dbc::parse(data).unwrap();
253
254 let payload = [0x40, 0x1F, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00];
257 let decoded = dbc.decode(256, &payload).unwrap();
258
259 assert_eq!(decoded.len(), 2);
260 assert_eq!(decoded[0].0, "RPM");
261 assert_eq!(decoded[0].1, 2000.0);
262 assert_eq!(decoded[0].2, Some("rpm"));
263 assert_eq!(decoded[1].0, "Temp");
264 assert_eq!(decoded[1].1, 50.0);
265 assert_eq!(decoded[1].2, Some("°C"));
266 }
267
268 #[test]
269 fn test_decode_payload_length_mismatch() {
270 use crate::Error;
271 let data = r#"VERSION "1.0"
272
273BU_: ECM
274
275BO_ 256 Engine : 8 ECM
276 SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm" *
277"#;
278
279 let dbc = Dbc::parse(data).unwrap();
280
281 let payload = [0x40, 0x1F, 0x00, 0x00];
283 let result = dbc.decode(256, &payload);
284 assert!(result.is_err());
285 match result.unwrap_err() {
286 Error::Decoding(msg) => {
287 assert!(msg.contains(Error::PAYLOAD_LENGTH_MISMATCH));
288 }
289 _ => panic!("Expected Error::Decoding"),
290 }
291 }
292
293 #[test]
294 fn test_decode_big_endian_signal() {
295 let data = r#"VERSION "1.0"
296
297BU_: ECM
298
299BO_ 256 Engine : 8 ECM
300 SG_ RPM : 0|16@0+ (1.0,0) [0|65535] "rpm" *
301"#;
302
303 let dbc = Dbc::parse(data).unwrap();
304
305 let payload = [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
309 let decoded = dbc.decode(256, &payload).unwrap();
310
311 assert_eq!(decoded.len(), 1);
312 assert_eq!(decoded[0].0, "RPM");
313 assert!(decoded[0].1 >= 0.0);
316 assert_eq!(decoded[0].2, Some("rpm"));
317 }
318
319 #[test]
320 fn test_decode_multiplexed_signal() {
321 let dbc = Dbc::parse(
322 r#"VERSION "1.0"
323
324BU_: ECM
325
326BO_ 256 Engine : 8 ECM
327 SG_ MuxId M : 0|8@1+ (1,0) [0|255] ""
328 SG_ Signal0 m0 : 8|16@1+ (0.1,0) [0|6553.5] "unit" *
329 SG_ Signal1 m1 : 24|16@1+ (0.01,0) [0|655.35] "unit" *
330 SG_ NormalSignal : 40|8@1+ (1,0) [0|255] ""
331"#,
332 )
333 .unwrap();
334
335 let payload = [0x00, 0x64, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00];
337 let decoded = dbc.decode(256, &payload).unwrap();
340
341 let find_signal =
343 |name: &str| decoded.iter().find(|(n, _, _)| *n == name).map(|(_, v, _)| *v);
344
345 assert!(find_signal("MuxId").is_some());
347 assert!(find_signal("Signal0").is_some());
349 assert!(find_signal("Signal1").is_none());
351 assert!(find_signal("NormalSignal").is_some());
353 }
354
355 #[test]
356 fn test_decode_multiplexed_signal_switch_one() {
357 let dbc = Dbc::parse(
358 r#"VERSION "1.0"
359
360BU_: ECM
361
362BO_ 256 Engine : 8 ECM
363 SG_ MuxId M : 0|8@1+ (1,0) [0|255] ""
364 SG_ Signal0 m0 : 8|16@1+ (0.1,0) [0|6553.5] "unit" *
365 SG_ Signal1 m1 : 24|16@1+ (0.01,0) [0|655.35] "unit" *
366"#,
367 )
368 .unwrap();
369
370 let payload = [0x01, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00];
372 let decoded = dbc.decode(256, &payload).unwrap();
375
376 let find_signal =
378 |name: &str| decoded.iter().find(|(n, _, _)| *n == name).map(|(_, v, _)| *v);
379
380 assert_eq!(find_signal("MuxId"), Some(1.0));
382 assert!(find_signal("Signal0").is_none());
384 assert!(find_signal("Signal1").is_some());
386 }
387
388 #[test]
389 fn test_decode_mixed_byte_order() {
390 let dbc = Dbc::parse(
391 r#"VERSION "1.0"
392
393BU_: ECM
394
395BO_ 256 MixedByteOrder : 8 ECM
396 SG_ LittleEndianSignal : 0|16@1+ (1.0,0) [0|65535] ""
397 SG_ BigEndianSignal : 16|16@0+ (1.0,0) [0|65535] ""
398 SG_ AnotherLittleEndian : 32|8@1+ (1.0,0) [0|255] ""
399 SG_ AnotherBigEndian : 40|8@0+ (1.0,0) [0|255] ""
400"#,
401 )
402 .unwrap();
403
404 let payload = [
410 0x34, 0x12, 0x00, 0x01, 0xAB, 0xCD, 0x00, 0x00, ];
416 let decoded = dbc.decode(256, &payload).unwrap();
417
418 let find_signal =
420 |name: &str| decoded.iter().find(|(n, _, _)| *n == name).map(|(_, v, _)| *v);
421
422 assert_eq!(find_signal("LittleEndianSignal"), Some(4660.0)); let big_endian_value = find_signal("BigEndianSignal").unwrap();
427 assert!((0.0..=65535.0).contains(&big_endian_value));
429
430 assert_eq!(find_signal("AnotherLittleEndian"), Some(171.0)); let big_endian_8bit = find_signal("AnotherBigEndian");
435 assert!(big_endian_8bit.is_some());
436 assert!(big_endian_8bit.unwrap() >= 0.0 && big_endian_8bit.unwrap() <= 255.0);
437
438 assert_eq!(decoded.len(), 4);
440
441 assert!(find_signal("LittleEndianSignal").is_some());
443 assert!(find_signal("BigEndianSignal").is_some());
444 }
445
446 #[test]
447 fn test_decode_extended_multiplexing_simple() {
448 let dbc = Dbc::parse(
449 r#"VERSION "1.0"
450
451BU_: ECM
452
453BO_ 500 ComplexMux : 8 ECM
454 SG_ Mux1 M : 0|8@1+ (1,0) [0|255] ""
455 SG_ Signal_A m0 : 16|16@1+ (0.1,0) [0|100] "unit" *
456
457SG_MUL_VAL_ 500 Signal_A Mux1 5-10 ;
458"#,
459 )
460 .unwrap();
461
462 let payload = [0x05, 0x00, 0xE8, 0x03, 0x00, 0x00, 0x00, 0x00];
466 let decoded = dbc.decode(500, &payload).unwrap();
467
468 let find_signal =
469 |name: &str| decoded.iter().find(|(n, _, _)| *n == name).map(|(_, v, _)| *v);
470
471 assert_eq!(find_signal("Mux1"), Some(5.0));
472 let ext_entries = dbc.extended_multiplexing_for_message(500);
474 assert_eq!(
475 ext_entries.len(),
476 1,
477 "Extended multiplexing entries should be parsed"
478 );
479 assert!(
480 find_signal("Signal_A").is_some(),
481 "Signal_A should be decoded when Mux1=5 (within range 5-10)"
482 );
483 assert_eq!(find_signal("Signal_A").unwrap(), 100.0);
484
485 let payload2 = [0x0F, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00];
487 let decoded2 = dbc.decode(500, &payload2).unwrap();
488 let find_signal2 =
489 |name: &str| decoded2.iter().find(|(n, _, _)| *n == name).map(|(_, v, _)| *v);
490
491 assert_eq!(find_signal2("Mux1"), Some(15.0));
492 assert!(find_signal2("Signal_A").is_none());
493 }
494
495 #[test]
496 fn test_decode_extended_multiplexing_multiple_ranges() {
497 let dbc = Dbc::parse(
498 r#"VERSION "1.0"
499
500BU_: ECM
501
502BO_ 501 MultiRangeMux : 8 ECM
503 SG_ Mux1 M : 0|8@1+ (1,0) [0|255] ""
504 SG_ Signal_B m0 : 16|16@1+ (1,0) [0|65535] "unit" *
505
506SG_MUL_VAL_ 501 Signal_B Mux1 0-5,10-15,20-25 ;
507"#,
508 )
509 .unwrap();
510
511 let payload1 = [0x03, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00];
514 let decoded1 = dbc.decode(501, &payload1).unwrap();
515 let find1 = |name: &str| decoded1.iter().find(|(n, _, _)| *n == name).map(|(_, v, _)| *v);
516 assert_eq!(find1("Mux1"), Some(3.0));
517 assert!(find1("Signal_B").is_some());
518
519 let payload2 = [0x0C, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00];
522 let decoded2 = dbc.decode(501, &payload2).unwrap();
523 let find2 = |name: &str| decoded2.iter().find(|(n, _, _)| *n == name).map(|(_, v, _)| *v);
524 assert_eq!(find2("Mux1"), Some(12.0));
525 assert!(find2("Signal_B").is_some());
526
527 let payload3 = [0x16, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00];
530 let decoded3 = dbc.decode(501, &payload3).unwrap();
531 let find3 = |name: &str| decoded3.iter().find(|(n, _, _)| *n == name).map(|(_, v, _)| *v);
532 assert_eq!(find3("Mux1"), Some(22.0));
533 assert!(find3("Signal_B").is_some());
534
535 let payload4 = [0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00];
538 let decoded4 = dbc.decode(501, &payload4).unwrap();
539 let find4 = |name: &str| decoded4.iter().find(|(n, _, _)| *n == name).map(|(_, v, _)| *v);
540 assert_eq!(find4("Mux1"), Some(8.0));
541 assert!(find4("Signal_B").is_none());
542 }
543
544 #[test]
547 fn test_decode_extended_multiplexing_multiple_switches() {
548 let dbc = Dbc::parse(
549 r#"VERSION "1.0"
550
551BU_: ECM
552
553BO_ 502 MultiSwitchMux : 8 ECM
554 SG_ Mux1 M : 0|8@1+ (1,0) [0|255] ""
555 SG_ Mux2 M : 8|8@1+ (1,0) [0|255] ""
556 SG_ Signal_C m0 : 16|16@1+ (1,0) [0|65535] "unit" *
557
558SG_MUL_VAL_ 502 Signal_C Mux1 5-10 ;
559SG_MUL_VAL_ 502 Signal_C Mux2 20-25 ;
560"#,
561 )
562 .unwrap();
563
564 let payload1 = [0x07, 0x16, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00];
567 let decoded1 = dbc.decode(502, &payload1).unwrap();
568 let find1 = |name: &str| decoded1.iter().find(|(n, _, _)| *n == name).map(|(_, v, _)| *v);
569 assert_eq!(find1("Mux1"), Some(7.0));
570 assert_eq!(find1("Mux2"), Some(22.0));
571 assert!(find1("Signal_C").is_some());
572
573 let payload2 = [0x07, 0x1E, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00];
575 let decoded2 = dbc.decode(502, &payload2).unwrap();
576 let find2 = |name: &str| decoded2.iter().find(|(n, _, _)| *n == name).map(|(_, v, _)| *v);
577 assert_eq!(find2("Mux1"), Some(7.0));
578 assert_eq!(find2("Mux2"), Some(30.0));
579 assert!(find2("Signal_C").is_none());
580
581 let payload3 = [0x0F, 0x16, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00];
583 let decoded3 = dbc.decode(502, &payload3).unwrap();
584 let find3 = |name: &str| decoded3.iter().find(|(n, _, _)| *n == name).map(|(_, v, _)| *v);
585 assert_eq!(find3("Mux1"), Some(15.0));
586 assert_eq!(find3("Mux2"), Some(22.0));
587 assert!(find3("Signal_C").is_none());
588 }
589
590 #[test]
593 fn test_decode_extended_multiplexing_takes_precedence() {
594 let dbc = Dbc::parse(
595 r#"VERSION "1.0"
596
597BU_: ECM
598
599BO_ 503 PrecedenceTest : 8 ECM
600 SG_ Mux1 M : 0|8@1+ (1,0) [0|255] ""
601 SG_ Signal_D m0 : 16|16@1+ (1,0) [0|65535] "unit" *
602
603SG_MUL_VAL_ 503 Signal_D Mux1 10-15 ;
604"#,
605 )
606 .unwrap();
607
608 let payload1 = [0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00];
612 let decoded1 = dbc.decode(503, &payload1).unwrap();
613 let find1 = |name: &str| decoded1.iter().find(|(n, _, _)| *n == name).map(|(_, v, _)| *v);
614 assert_eq!(find1("Mux1"), Some(0.0));
615 assert!(find1("Signal_D").is_none());
616
617 let payload2 = [0x0C, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00];
619 let decoded2 = dbc.decode(503, &payload2).unwrap();
620 let find2 = |name: &str| decoded2.iter().find(|(n, _, _)| *n == name).map(|(_, v, _)| *v);
621 assert_eq!(find2("Mux1"), Some(12.0));
622 assert!(find2("Signal_D").is_some());
623 }
624
625 #[test]
628 fn test_decode_extended_multiplexing_with_extended_mux_signal() {
629 let dbc = Dbc::parse(
631 r#"VERSION "1.0"
632
633BU_: ECM
634
635BO_ 504 ExtendedMuxSignal : 8 ECM
636 SG_ Mux1 M : 0|8@1+ (1,0) [0|255] ""
637 SG_ Mux2 m65M : 8|8@1+ (1,0) [0|255] ""
638 SG_ Signal_E m0 : 16|16@1+ (1,0) [0|65535] "unit" *
639
640SG_MUL_VAL_ 504 Signal_E Mux1 65-65 ;
641SG_MUL_VAL_ 504 Signal_E Mux2 10-15 ;
642"#,
643 )
644 .unwrap();
645
646 let payload = [0x41, 0x0C, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x00];
649 let decoded = dbc.decode(504, &payload).unwrap();
651 let find = |name: &str| decoded.iter().find(|(n, _, _)| *n == name).map(|(_, v, _)| *v);
652
653 assert_eq!(find("Mux1"), Some(65.0));
654 assert_eq!(find("Mux2"), Some(12.0));
655 assert!(find("Signal_E").is_some());
656
657 let payload2 = [0x40, 0x0C, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00];
659 let decoded2 = dbc.decode(504, &payload2).unwrap();
660 let find2 = |name: &str| decoded2.iter().find(|(n, _, _)| *n == name).map(|(_, v, _)| *v);
661 assert_eq!(find2("Mux1"), Some(64.0));
662 assert_eq!(find2("Mux2"), Some(12.0));
663 assert!(find2("Signal_E").is_none());
664 }
665
666 #[test]
667 fn test_decode_negative_multiplexer_switch() {
668 use crate::Error;
669 let dbc = Dbc::parse(
672 r#"VERSION "1.0"
673
674BU_: ECM
675
676BO_ 256 MuxMessage : 8 ECM
677 SG_ MuxSwitch M : 0|8@1- (1,0) [-128|127] ""
678 SG_ SignalA m0 : 8|8@1+ (1,0) [0|255] ""
679"#,
680 )
681 .unwrap();
682
683 let payload = [0xFB, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
687 let result = dbc.decode(256, &payload);
688 assert!(result.is_err());
689 match result.unwrap_err() {
690 Error::Decoding(msg) => {
691 assert_eq!(msg, Error::MULTIPLEXER_SWITCH_NEGATIVE);
692 }
693 _ => panic!("Expected Error::Decoding with MULTIPLEXER_SWITCH_NEGATIVE"),
694 }
695 }
696
697 #[test]
698 fn test_decode_too_many_unique_switches() {
699 use crate::{Error, MAX_SIGNALS_PER_MESSAGE};
700 if MAX_SIGNALS_PER_MESSAGE < 17 {
703 return;
704 }
705
706 let dbc_str = r#"VERSION "1.0"
710
711BU_: ECM
712
713BO_ 600 TooManySwitches : 18 ECM
714 SG_ Mux1 M : 0|8@1+ (1,0) [0|255] ""
715 SG_ Mux2 M : 8|8@1+ (1,0) [0|255] ""
716 SG_ Mux3 M : 16|8@1+ (1,0) [0|255] ""
717 SG_ Mux4 M : 24|8@1+ (1,0) [0|255] ""
718 SG_ Mux5 M : 32|8@1+ (1,0) [0|255] ""
719 SG_ Mux6 M : 40|8@1+ (1,0) [0|255] ""
720 SG_ Mux7 M : 48|8@1+ (1,0) [0|255] ""
721 SG_ Mux8 M : 56|8@1+ (1,0) [0|255] ""
722 SG_ Mux9 M : 64|8@1+ (1,0) [0|255] ""
723 SG_ Mux10 M : 72|8@1+ (1,0) [0|255] ""
724 SG_ Mux11 M : 80|8@1+ (1,0) [0|255] ""
725 SG_ Mux12 M : 88|8@1+ (1,0) [0|255] ""
726 SG_ Mux13 M : 96|8@1+ (1,0) [0|255] ""
727 SG_ Mux14 M : 104|8@1+ (1,0) [0|255] ""
728 SG_ Mux15 M : 112|8@1+ (1,0) [0|255] ""
729 SG_ Mux16 M : 120|8@1+ (1,0) [0|255] ""
730 SG_ Mux17 M : 128|8@1+ (1,0) [0|255] ""
731 SG_ Signal_X m0 : 136|8@1+ (1,0) [0|255] "unit" *
732
733SG_MUL_VAL_ 600 Signal_X Mux1 0-255 ;
734SG_MUL_VAL_ 600 Signal_X Mux2 0-255 ;
735SG_MUL_VAL_ 600 Signal_X Mux3 0-255 ;
736SG_MUL_VAL_ 600 Signal_X Mux4 0-255 ;
737SG_MUL_VAL_ 600 Signal_X Mux5 0-255 ;
738SG_MUL_VAL_ 600 Signal_X Mux6 0-255 ;
739SG_MUL_VAL_ 600 Signal_X Mux7 0-255 ;
740SG_MUL_VAL_ 600 Signal_X Mux8 0-255 ;
741SG_MUL_VAL_ 600 Signal_X Mux9 0-255 ;
742SG_MUL_VAL_ 600 Signal_X Mux10 0-255 ;
743SG_MUL_VAL_ 600 Signal_X Mux11 0-255 ;
744SG_MUL_VAL_ 600 Signal_X Mux12 0-255 ;
745SG_MUL_VAL_ 600 Signal_X Mux13 0-255 ;
746SG_MUL_VAL_ 600 Signal_X Mux14 0-255 ;
747SG_MUL_VAL_ 600 Signal_X Mux15 0-255 ;
748SG_MUL_VAL_ 600 Signal_X Mux16 0-255 ;
749SG_MUL_VAL_ 600 Signal_X Mux17 0-255 ;
750"#;
751
752 let dbc = Dbc::parse(dbc_str).unwrap();
753
754 let payload = [0x00; 18];
757 let result = dbc.decode(600, &payload);
758 assert!(
759 result.is_err(),
760 "Decode should fail when there are more than 16 unique switches"
761 );
762 match result.unwrap_err() {
763 Error::Decoding(msg) => {
764 assert_eq!(
765 msg,
766 Error::MESSAGE_TOO_MANY_SIGNALS,
767 "Expected MESSAGE_TOO_MANY_SIGNALS error, got: {}",
768 msg
769 );
770 }
771 e => panic!(
772 "Expected Error::Decoding with MESSAGE_TOO_MANY_SIGNALS, got: {:?}",
773 e
774 ),
775 }
776 }
777}