Skip to main content

dbc_rs/extended_multiplexing/
impls.rs

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