can_dbc/ast/
signal_groups.rs

1use can_dbc_pest::{Pair, Rule};
2
3use crate::ast::MessageId;
4use crate::parser::{
5    collect_strings, expect_empty, next_rule, next_string, parse_next_uint, validated_inner,
6    DbcError,
7};
8
9/// Signal groups define a group of signals within a message
10#[derive(Clone, Debug, PartialEq)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub struct SignalGroups {
13    pub message_id: MessageId,
14    pub name: String,
15    pub repetitions: u64,
16    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
17    pub signal_names: Vec<String>,
18}
19
20impl TryFrom<Pair<'_, Rule>> for SignalGroups {
21    type Error = DbcError;
22
23    /// Parse signal group: `SIG_GROUP_ message_id group_name multiplexer_id : signal1 signal2 ... ;`
24    fn try_from(value: Pair<'_, Rule>) -> Result<Self, Self::Error> {
25        let mut pairs = validated_inner(value, Rule::signal_group)?;
26
27        let value = Self {
28            message_id: next_rule(&mut pairs, Rule::message_id)?.try_into()?,
29            name: next_string(&mut pairs, Rule::group_name)?,
30            repetitions: parse_next_uint(&mut pairs, Rule::multiplexer_id)?,
31            signal_names: collect_strings(&mut pairs, Rule::signal_name)?,
32        };
33        expect_empty(&pairs)?;
34
35        Ok(value)
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42    use crate::test_helpers::*;
43
44    #[test]
45    fn signal_groups_test() {
46        let def = "
47SIG_GROUP_ 23 X_3290 1 : A_b XY_Z;
48";
49        let exp = SignalGroups {
50            message_id: MessageId::Standard(23),
51            name: "X_3290".to_string(),
52            repetitions: 1,
53            signal_names: vec!["A_b".to_string(), "XY_Z".to_string()],
54        };
55        let val = test_into::<SignalGroups>(def.trim_start(), Rule::signal_group);
56        assert_eq!(val, exp);
57    }
58}