can_dbc/ast/
environment_variable.rs1use can_dbc_pest::{Pair, Rule};
2
3use crate::ast::{AccessType, EnvType};
4use crate::parser::{
5 collect_node_names, expect_empty, inner_str, next, next_optional_rule, next_rule, parse_int,
6 parse_min_max_int, single_inner_str, validated_inner, DbcError,
7};
8
9#[derive(Clone, Debug, PartialEq)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct EnvironmentVariable {
12 pub name: String,
13 pub typ: EnvType,
14 pub min: i64,
15 pub max: i64,
16 pub unit: String,
17 pub initial_value: i64,
18 pub ev_id: i64,
19 pub access_type: AccessType,
20 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
21 pub access_nodes: Vec<String>,
22}
23
24impl TryFrom<Pair<'_, Rule>> for EnvironmentVariable {
25 type Error = DbcError;
26
27 fn try_from(value: Pair<'_, Rule>) -> Result<Self, Self::Error> {
29 let mut pairs = validated_inner(value, Rule::environment_variable)?;
31
32 let name = single_inner_str(next_rule(&mut pairs, Rule::env_var)?, Rule::env_var_name)?;
34
35 let typ = next(&mut pairs)?.as_rule().try_into()?;
37
38 let (mut min, mut max) = (0i64, 0i64);
40 if let Some(min_max_pair) = next_optional_rule(&mut pairs, Rule::min_max) {
41 (min, max) = parse_min_max_int(min_max_pair)?;
42 }
43
44 let mut unit = String::new();
46 if let Some(unit_pair) = next_optional_rule(&mut pairs, Rule::unit) {
47 unit = inner_str(unit_pair);
48 }
49
50 let mut initial_value = 0;
52 if let Some(init_pair) = next_optional_rule(&mut pairs, Rule::init_value) {
53 initial_value = parse_int(&init_pair)?;
54 }
55
56 let mut ev_id = 0i64;
58 if let Some(ev_pair) = next_optional_rule(&mut pairs, Rule::ev_id) {
59 ev_id = parse_int(&ev_pair)?;
60 }
61
62 let access_type = next_rule(&mut pairs, Rule::access_type)?.try_into()?;
64
65 let access_nodes = collect_node_names(&mut pairs, Rule::node_name)?;
67
68 expect_empty(&pairs)?;
69
70 Ok(Self {
71 name,
72 typ,
73 min,
74 max,
75 unit,
76 initial_value,
77 ev_id,
78 access_type,
79 access_nodes,
80 })
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87 use crate::test_helpers::*;
88
89 #[test]
90 fn environment_variable_test() {
91 let def = r#"
96EV_ IUV: 0 [-22|20] "mm" 3 7 DUMMY_NODE_VECTOR0 VECTOR_XXX;
97"#;
98 let exp = EnvironmentVariable {
99 name: "IUV".to_string(),
100 typ: EnvType::Integer,
101 min: -22,
102 max: 20,
103 unit: "mm".to_string(),
104 initial_value: 3,
105 ev_id: 7,
106 access_type: AccessType::DummyNodeVector0,
107 access_nodes: vec!["VECTOR_XXX".to_string()],
108 };
109 let val = test_into::<EnvironmentVariable>(def.trim_start(), Rule::environment_variable);
110 assert_eq!(val, exp);
111 }
112
113 #[test]
114 fn vector_placeholder_access_node_test() {
115 let def = r#"
116EV_ IUV: 0 [-22|20] "mm" 3 7 DUMMY_NODE_VECTOR0 Vector__XXX;
117"#;
118 let val = test_into::<EnvironmentVariable>(def.trim_start(), Rule::environment_variable);
119 assert_eq!(val.access_nodes, Vec::<String>::new());
120 }
121}