dbc_rs/extended_multiplexing/impls.rs
1use super::{ExtendedMultiplexing, ValueRanges};
2use crate::compat::Name;
3
4impl ExtendedMultiplexing {
5 pub(crate) fn new(
6 message_id: u32,
7 signal_name: Name,
8 multiplexer_switch: Name,
9 value_ranges: ValueRanges,
10 ) -> Self {
11 Self {
12 message_id,
13 signal_name,
14 multiplexer_switch,
15 value_ranges,
16 }
17 }
18
19 /// Returns the CAN message ID this extended multiplexing entry applies to.
20 ///
21 /// # Examples
22 ///
23 /// ```rust,no_run
24 /// use dbc_rs::Dbc;
25 ///
26 /// let dbc = Dbc::parse(r#"VERSION "1.0"
27 ///
28 /// BU_: ECM
29 ///
30 /// BO_ 500 MuxMessage : 8 ECM
31 /// SG_ Mux1 M : 0|8@1+ (1,0) [0|255] ""
32 /// SG_ Signal_A m0 : 16|16@1+ (0.1,0) [0|100] "unit" *
33 ///
34 /// SG_MUL_VAL_ 500 Signal_A Mux1 5-10 ;
35 /// "#)?;
36 ///
37 /// let entry = dbc.extended_multiplexing_for_message(500).next().unwrap();
38 /// assert_eq!(entry.message_id(), 500);
39 /// # Ok::<(), dbc_rs::Error>(())
40 /// ```
41 #[inline]
42 #[must_use = "return value should be used"]
43 pub fn message_id(&self) -> u32 {
44 self.message_id
45 }
46
47 /// Returns the name of the signal this extended multiplexing entry controls.
48 ///
49 /// The signal will only be decoded when the multiplexer switch value falls
50 /// within one of the defined value ranges.
51 ///
52 /// # Examples
53 ///
54 /// ```rust,no_run
55 /// use dbc_rs::Dbc;
56 ///
57 /// let dbc = Dbc::parse(r#"VERSION "1.0"
58 ///
59 /// BU_: ECM
60 ///
61 /// BO_ 500 MuxMessage : 8 ECM
62 /// SG_ Mux1 M : 0|8@1+ (1,0) [0|255] ""
63 /// SG_ Signal_A m0 : 16|16@1+ (0.1,0) [0|100] "unit" *
64 ///
65 /// SG_MUL_VAL_ 500 Signal_A Mux1 5-10 ;
66 /// "#)?;
67 ///
68 /// let entry = dbc.extended_multiplexing_for_message(500).next().unwrap();
69 /// assert_eq!(entry.signal_name(), "Signal_A");
70 /// # Ok::<(), dbc_rs::Error>(())
71 /// ```
72 #[inline]
73 #[must_use = "return value should be used"]
74 pub fn signal_name(&self) -> &str {
75 self.signal_name.as_str()
76 }
77
78 /// Returns the name of the multiplexer switch signal that controls activation.
79 ///
80 /// The multiplexer switch is a signal marked with `M` in the DBC file. When
81 /// decoding, the switch's current value is compared against the value ranges
82 /// to determine if the controlled signal should be decoded.
83 ///
84 /// # Examples
85 ///
86 /// ```rust,no_run
87 /// use dbc_rs::Dbc;
88 ///
89 /// let dbc = Dbc::parse(r#"VERSION "1.0"
90 ///
91 /// BU_: ECM
92 ///
93 /// BO_ 500 MuxMessage : 8 ECM
94 /// SG_ Mux1 M : 0|8@1+ (1,0) [0|255] ""
95 /// SG_ Signal_A m0 : 16|16@1+ (0.1,0) [0|100] "unit" *
96 ///
97 /// SG_MUL_VAL_ 500 Signal_A Mux1 5-10 ;
98 /// "#)?;
99 ///
100 /// let entry = dbc.extended_multiplexing_for_message(500).next().unwrap();
101 /// assert_eq!(entry.multiplexer_switch(), "Mux1");
102 /// # Ok::<(), dbc_rs::Error>(())
103 /// ```
104 #[inline]
105 #[must_use = "return value should be used"]
106 pub fn multiplexer_switch(&self) -> &str {
107 self.multiplexer_switch.as_str()
108 }
109
110 /// Returns the value ranges that activate the controlled signal.
111 ///
112 /// Each tuple `(min, max)` defines an inclusive range. The signal is decoded
113 /// when the multiplexer switch value falls within **any** of these ranges.
114 ///
115 /// For example, `[(0, 5), (10, 15)]` means the signal is active when the
116 /// switch value is 0-5 OR 10-15.
117 ///
118 /// # Examples
119 ///
120 /// ```rust,no_run
121 /// use dbc_rs::Dbc;
122 ///
123 /// let dbc = Dbc::parse(r#"VERSION "1.0"
124 ///
125 /// BU_: ECM
126 ///
127 /// BO_ 500 MuxMessage : 8 ECM
128 /// SG_ Mux1 M : 0|8@1+ (1,0) [0|255] ""
129 /// SG_ Signal_A m0 : 16|16@1+ (0.1,0) [0|100] "unit" *
130 ///
131 /// SG_MUL_VAL_ 500 Signal_A Mux1 0-5,10-15 ;
132 /// "#)?;
133 ///
134 /// let entry = dbc.extended_multiplexing_for_message(500).next().unwrap();
135 /// let ranges = entry.value_ranges();
136 ///
137 /// // Check if switch value 3 activates the signal
138 /// let switch_value = 3u64;
139 /// let is_active = ranges.iter().any(|(min, max)| switch_value >= *min && switch_value <= *max);
140 /// assert!(is_active);
141 /// # Ok::<(), dbc_rs::Error>(())
142 /// ```
143 #[inline]
144 #[must_use = "return value should be used"]
145 pub fn value_ranges(&self) -> &[(u64, u64)] {
146 self.value_ranges.as_slice()
147 }
148}