use can_dbc_pest::{Pair, Rule};
use crate::ast::MessageId;
use crate::parser::{
collect_strings, expect_empty, next_rule, next_string, parse_next_uint, validated_inner,
DbcError,
};
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SignalGroups {
pub message_id: MessageId,
pub name: String,
pub repetitions: u64,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
pub signal_names: Vec<String>,
}
impl TryFrom<Pair<'_, Rule>> for SignalGroups {
type Error = DbcError;
fn try_from(value: Pair<'_, Rule>) -> Result<Self, Self::Error> {
let mut pairs = validated_inner(value, Rule::signal_group)?;
let value = Self {
message_id: next_rule(&mut pairs, Rule::message_id)?.try_into()?,
name: next_string(&mut pairs, Rule::group_name)?,
repetitions: parse_next_uint(&mut pairs, Rule::multiplexer_id)?,
signal_names: collect_strings(&mut pairs, Rule::signal_name)?,
};
expect_empty(&pairs)?;
Ok(value)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_helpers::*;
#[test]
fn signal_groups_test() {
let def = "
SIG_GROUP_ 23 X_3290 1 : A_b XY_Z;
";
let exp = SignalGroups {
message_id: MessageId::Standard(23),
name: "X_3290".to_string(),
repetitions: 1,
signal_names: vec!["A_b".to_string(), "XY_Z".to_string()],
};
let val = test_into::<SignalGroups>(def.trim_start(), Rule::signal_group);
assert_eq!(val, exp);
}
}