can_dbc/ast/
extended_multiplex.rs

1use can_dbc_pest::{Pair, Rule};
2
3use crate::ast::{ExtendedMultiplexMapping, MessageId};
4use crate::parser::{collect_all, next_rule, next_string, validated_inner, DbcError};
5
6/// Mapping between multiplexors and multiplexed signals
7#[derive(Clone, Debug, PartialEq)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9pub struct ExtendedMultiplex {
10    pub message_id: MessageId,
11    pub signal_name: String,
12    pub multiplexor_signal_name: String,
13    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
14    pub mappings: Vec<ExtendedMultiplexMapping>,
15}
16
17impl TryFrom<Pair<'_, Rule>> for ExtendedMultiplex {
18    type Error = DbcError;
19
20    fn try_from(value: Pair<'_, Rule>) -> Result<Self, Self::Error> {
21        let mut pairs = validated_inner(value, Rule::sg_mul_val)?;
22
23        let message_id = next_rule(&mut pairs, Rule::message_id)?.try_into()?;
24        let signal_name = next_string(&mut pairs, Rule::signal_name)?;
25        let multiplexor_signal_name = next_string(&mut pairs, Rule::multiplexer_name)?;
26
27        // Collect all remaining value pairs
28        let mappings: Vec<ExtendedMultiplexMapping> =
29            collect_all::<ExtendedMultiplexMapping>(&mut pairs)?;
30
31        Ok(Self {
32            message_id,
33            signal_name,
34            multiplexor_signal_name,
35            mappings,
36        })
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43    use crate::test_helpers::*;
44
45    #[test]
46    fn extended_multiplex_test() {
47        // simple mapping
48        let def = "
49SG_MUL_VAL_ 2147483650 muxed_A_1 MUX_A 1-1;
50";
51        let exp = ExtendedMultiplex {
52            message_id: MessageId::Extended(2),
53            signal_name: "muxed_A_1".to_string(),
54            multiplexor_signal_name: "MUX_A".to_string(),
55            mappings: vec![ExtendedMultiplexMapping {
56                min_value: 1,
57                max_value: 1,
58            }],
59        };
60        let val = test_into::<ExtendedMultiplex>(def.trim_start(), Rule::sg_mul_val);
61        assert_eq!(val, exp);
62    }
63
64    #[test]
65    fn extended_multiplex_range_test() {
66        // range mapping
67        let def = "
68SG_MUL_VAL_ 2147483650 muxed_A_1 MUX_A 1568-2568;
69";
70        let exp = ExtendedMultiplex {
71            message_id: MessageId::Extended(2),
72            signal_name: "muxed_A_1".to_string(),
73            multiplexor_signal_name: "MUX_A".to_string(),
74            mappings: vec![ExtendedMultiplexMapping {
75                min_value: 1568,
76                max_value: 2568,
77            }],
78        };
79        let val = test_into::<ExtendedMultiplex>(def.trim_start(), Rule::sg_mul_val);
80        assert_eq!(val, exp);
81    }
82
83    #[test]
84    fn extended_multiplex_mult_test() {
85        // multiple mappings
86        let def = "
87SG_MUL_VAL_ 2147483650 muxed_B_5 MUX_B 5-5, 16-24;
88";
89        let exp = ExtendedMultiplex {
90            message_id: MessageId::Extended(2),
91            signal_name: "muxed_B_5".to_string(),
92            multiplexor_signal_name: "MUX_B".to_string(),
93            mappings: vec![
94                ExtendedMultiplexMapping {
95                    min_value: 5,
96                    max_value: 5,
97                },
98                ExtendedMultiplexMapping {
99                    min_value: 16,
100                    max_value: 24,
101                },
102            ],
103        };
104        let val = test_into::<ExtendedMultiplex>(def.trim_start(), Rule::sg_mul_val);
105        assert_eq!(val, exp);
106    }
107}