can_dbc/ast/
environment_variable.rs1use can_dbc_pest::{Pair, Rule};
2
3use crate::ast::{AccessNode, AccessType, EnvType};
4use crate::parser::{
5 collect_expected, 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<AccessNode>,
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_expected::<AccessNode>(&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#"
92EV_ IUV: 0 [-22|20] "mm" 3 7 DUMMY_NODE_VECTOR0 VECTOR_XXX;
93"#;
94 let exp = EnvironmentVariable {
95 name: "IUV".to_string(),
96 typ: EnvType::Integer,
97 min: -22,
98 max: 20,
99 unit: "mm".to_string(),
100 initial_value: 3,
101 ev_id: 7,
102 access_type: AccessType::DummyNodeVector0,
103 access_nodes: vec![AccessNode::Name("VECTOR_XXX".to_string())],
104 };
105 let val = test_into::<EnvironmentVariable>(def.trim_start(), Rule::environment_variable);
106 assert_eq!(val, exp);
107 }
108}