can_dbc/ast/
multiplex_indicator.rs

1use std::str;
2
3use crate::parser::DbcError;
4
5#[derive(Copy, Clone, Debug, PartialEq)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7pub enum MultiplexIndicator {
8    /// Multiplexor switch
9    Multiplexor,
10    /// Signal is being multiplexed by the multiplexer switch.
11    MultiplexedSignal(u64),
12    /// Signal is being multiplexed by the multiplexer switch and itself is a multiplexer
13    MultiplexorAndMultiplexedSignal(u64),
14    /// Normal signal
15    Plain,
16}
17
18impl TryFrom<&str> for MultiplexIndicator {
19    type Error = DbcError;
20
21    fn try_from(text: &str) -> Result<Self, Self::Error> {
22        if text == "M" {
23            return Ok(Self::Multiplexor);
24        }
25        if let Some(text) = text.strip_prefix('m') {
26            // Multiplexed signal value should be like "m1" or "m1M"
27            // Check if it ends with 'M' (multiplexer and multiplexed signal)
28            if text.is_empty() {
29                // FIXME: is this the right interpretation?
30                return Ok(Self::Plain);
31            } else if let Some(text) = text.strip_suffix('M') {
32                if let Ok(value) = text.parse::<u64>() {
33                    return Ok(Self::MultiplexorAndMultiplexedSignal(value));
34                }
35            } else if let Ok(value) = text.parse::<u64>() {
36                return Ok(Self::MultiplexedSignal(value));
37            }
38        }
39
40        Err(Self::Error::UnknownMultiplexIndicator(text.to_string()))
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47
48    #[test]
49    fn multiplexer_indicator_test() {
50        let val: MultiplexIndicator = "m34920".try_into().unwrap();
51        assert_eq!(val, MultiplexIndicator::MultiplexedSignal(34920));
52
53        let val: MultiplexIndicator = "M".try_into().unwrap();
54        assert_eq!(val, MultiplexIndicator::Multiplexor);
55
56        // Empty string is not a valid multiplexer indicator, so we skip this test
57        // let val: MultiplexIndicator = "".try_into().unwrap();
58        // assert_eq!(val, MultiplexIndicator::Plain);
59
60        let val: MultiplexIndicator = "m8M".try_into().unwrap();
61        assert_eq!(val, MultiplexIndicator::MultiplexorAndMultiplexedSignal(8));
62    }
63}