can_dbc/ast/
attribute_definition.rs1use can_dbc_pest::{Pair, Rule};
2
3use crate::parser::{expect_empty, inner_str, next, next_optional_rule, next_rule, DbcError};
4use crate::AttributeValueType;
5
6#[derive(Clone, Debug, PartialEq)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub enum AttributeDefinition {
9 Message(String, AttributeValueType),
10 Node(String, AttributeValueType),
11 Signal(String, AttributeValueType),
12 EnvironmentVariable(String, AttributeValueType),
13 Plain(String, AttributeValueType),
14}
15
16impl TryFrom<Pair<'_, Rule>> for AttributeDefinition {
17 type Error = DbcError;
18
19 fn try_from(pair: Pair<'_, Rule>) -> Result<Self, Self::Error> {
21 let rule = pair.as_rule();
22 let expected = match rule {
23 Rule::attr_def => Rule::object_type,
24 Rule::ba_def_rel => Rule::rel_object_type,
25 v => Err(DbcError::ExpectedOneOfRules(
26 vec![Rule::attr_def, Rule::ba_def_rel],
27 v,
28 ))?,
29 };
30 let mut pairs = pair.into_inner();
31 let object_type = if let Some(v) = next_optional_rule(&mut pairs, expected) {
32 v.as_str().to_string()
33 } else {
34 String::new()
35 };
36
37 let name = inner_str(next_rule(&mut pairs, Rule::attribute_name)?);
38 let value = next(&mut pairs)?.try_into()?;
39 expect_empty(&pairs)?;
40
41 Ok(match object_type.as_str() {
42 "SG_" | "BU_SG_REL_" => Self::Signal(name, value),
43 "BO_" | "BU_BO_REL_" => Self::Message(name, value),
44 "BU_" => Self::Node(name, value),
45 "EV_" | "BU_EV_REL_" => Self::EnvironmentVariable(name, value),
46 _ => Self::Plain(name, value),
47 })
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54 use crate::ast::{AttributeValueType, NumericValue};
55 use crate::test_helpers::*;
56
57 #[test]
58 fn attribute_definition_bo_test() {
59 let def = r#"
60BA_DEF_ BO_ "BaDef1BO" INT 0 1000000;
61"#;
62 let exp = AttributeDefinition::Message(
63 "BaDef1BO".to_string(),
64 AttributeValueType::Int(NumericValue::Uint(0), NumericValue::Uint(1_000_000)),
65 );
66 let val = test_into::<AttributeDefinition>(def.trim_start(), Rule::attr_def);
67 assert_eq!(val, exp);
68 }
69
70 #[test]
71 fn attribute_definition_bo_txt_test() {
72 let def = r#"
73BA_DEF_ BO_ "GenMsgSendType" STRING ;
74"#;
75 let exp =
76 AttributeDefinition::Message("GenMsgSendType".to_string(), AttributeValueType::String);
77 let val = test_into::<AttributeDefinition>(def.trim_start(), Rule::attr_def);
78 assert_eq!(val, exp);
79 }
80
81 #[test]
82 fn attribute_definition_bu_test() {
83 let def = r#"
84BA_DEF_ BU_ "BuDef1BO" INT 0 1000000;
85"#;
86 let exp = AttributeDefinition::Node(
87 "BuDef1BO".to_string(),
88 AttributeValueType::Int(NumericValue::Uint(0), NumericValue::Uint(1_000_000)),
89 );
90 let val = test_into::<AttributeDefinition>(def.trim_start(), Rule::attr_def);
91 assert_eq!(val, exp);
92 }
93
94 #[test]
95 fn attribute_definition_sg_test() {
96 let def = r#"
97BA_DEF_ SG_ "SgDef1BO" INT 0 1000000;
98"#;
99 let exp = AttributeDefinition::Signal(
100 "SgDef1BO".to_string(),
101 AttributeValueType::Int(NumericValue::Uint(0), NumericValue::Uint(1_000_000)),
102 );
103 let val = test_into::<AttributeDefinition>(def.trim_start(), Rule::attr_def);
104 assert_eq!(val, exp);
105 }
106
107 #[test]
108 fn attribute_definition_ev_test() {
109 let def = r#"
110BA_DEF_ EV_ "EvDef1BO" INT 0 1000000;
111"#;
112 let exp = AttributeDefinition::EnvironmentVariable(
113 "EvDef1BO".to_string(),
114 AttributeValueType::Int(NumericValue::Uint(0), NumericValue::Uint(1_000_000)),
115 );
116 let val = test_into::<AttributeDefinition>(def.trim_start(), Rule::attr_def);
117 assert_eq!(val, exp);
118 }
119}