1use yaserde_derive::{YaDeserialize, YaSerialize};
2
3use crate::default_wrapper;
4
5#[derive(Clone, Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
7pub enum Causality {
8 #[yaserde(rename = "parameter")]
9 Parameter,
10 #[yaserde(rename = "calculatedParameter")]
11 CalculatedParameter,
12 #[yaserde(rename = "input")]
13 Input,
14 #[yaserde(rename = "output")]
15 Output,
16 #[default]
17 #[yaserde(rename = "local")]
18 Local,
19 #[yaserde(rename = "independent")]
20 Independent,
21}
22
23#[derive(Clone, Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
27pub enum Variability {
28 #[yaserde(rename = "constant")]
30 Constant,
31 #[yaserde(rename = "fixed")]
33 Fixed,
34 #[yaserde(rename = "tunable")]
36 Tunable,
37 #[yaserde(rename = "discrete")]
40 Discrete,
41 #[default]
45 #[yaserde(rename = "continuous")]
46 Continuous,
47}
48
49#[derive(Clone, Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
50pub enum Initial {
51 #[default]
52 #[yaserde(rename = "exact")]
53 Exact,
54 #[yaserde(rename = "approx")]
55 Approx,
56 #[yaserde(rename = "calculated")]
57 Calculated,
58}
59
60#[derive(Clone, Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
61pub struct Real {
62 #[yaserde(attribute = true, rename = "declaredType")]
64 pub declared_type: Option<String>,
65
66 #[yaserde(attribute = true)]
69 pub start: Option<f64>,
70
71 #[yaserde(attribute = true)]
74 pub derivative: Option<u32>,
75
76 #[yaserde(attribute = true, rename = "reinit")]
80 pub reinit: Option<bool>,
81}
82
83#[derive(Clone, Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
84pub struct Integer {
85 #[yaserde(attribute = true, rename = "declaredType")]
87 pub declared_type: Option<String>,
88
89 #[yaserde(attribute = true)]
92 pub start: Option<i32>,
93}
94
95#[derive(Clone, Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
96pub struct Boolean {
97 #[yaserde(attribute = true, rename = "declaredType")]
99 pub declared_type: Option<String>,
100
101 #[yaserde(attribute = true)]
103 pub start: Option<bool>,
104}
105
106#[derive(Clone, PartialEq, Debug, YaSerialize, YaDeserialize)]
107pub enum ScalarVariableElement {
108 #[yaserde(flatten = true)]
109 Real(Real),
110 #[yaserde(flatten = true)]
111 Integer(Integer),
112 #[yaserde(flatten = true)]
113 Boolean(Boolean),
114 #[yaserde(flatten = true)]
115 String,
116 #[yaserde(flatten = true)]
117 Enumeration,
118}
119
120impl Default for ScalarVariableElement {
121 fn default() -> Self {
122 Self::Real(Real::default())
123 }
124}
125
126#[cfg(feature = "arrow")]
127impl ScalarVariableElement {
128 pub fn data_type(&self) -> arrow::datatypes::DataType {
129 match self {
130 ScalarVariableElement::Real(_) => arrow::datatypes::DataType::Float64,
131 ScalarVariableElement::Integer(_) => arrow::datatypes::DataType::Int32,
132 ScalarVariableElement::Boolean(_) => arrow::datatypes::DataType::Boolean,
133 ScalarVariableElement::String => arrow::datatypes::DataType::Utf8,
134 ScalarVariableElement::Enumeration => arrow::datatypes::DataType::Int32,
135 }
136 }
137}
138
139#[derive(Default, Debug, YaSerialize, YaDeserialize)]
140pub struct ScalarVariable {
141 #[yaserde(attribute = true)]
143 pub name: String,
144
145 #[yaserde(attribute = true, rename = "valueReference")]
147 pub value_reference: u32,
148
149 #[yaserde(attribute = true)]
151 pub description: Option<String>,
152
153 #[yaserde(attribute = true, default = "default_wrapper")]
155 pub causality: Causality,
156
157 #[yaserde(attribute = true, default = "default_wrapper")]
160 pub variability: Variability,
161
162 #[yaserde(attribute = true)]
165 pub initial: Option<Initial>,
166
167 #[yaserde(flatten = true)]
168 pub elem: ScalarVariableElement,
169}
170
171impl ScalarVariable {
172 pub fn is_continuous_input(&self) -> bool {
173 matches!(
174 (&self.elem, &self.causality),
175 (ScalarVariableElement::Real { .. }, Causality::Input)
176 )
177 }
178}
179
180#[cfg(test)]
181mod tests {
182 use super::*;
183
184 #[test]
185 fn test_scalar_variable() {
186 let s = r#"
187 <ScalarVariable
188 name="inertia1.J"
189 valueReference="1073741824"
190 description="Moment of load inertia"
191 causality="parameter"
192 variability="fixed">
193 <Real declaredType="Modelica.SIunits.Inertia" start="1"/>
194 </ScalarVariable>
195 "#;
196 let sv: ScalarVariable = yaserde::de::from_str(s).unwrap();
197 assert_eq!(sv.name, "inertia1.J");
198 assert_eq!(sv.value_reference, 1073741824);
199 assert_eq!(sv.description, Some("Moment of load inertia".into()));
200 assert_eq!(sv.causality, Causality::Parameter);
201 assert_eq!(sv.variability, Variability::Fixed);
202 assert_eq!(
203 sv.elem,
204 ScalarVariableElement::Real(Real {
205 declared_type: Some("Modelica.SIunits.Inertia".to_string()),
206 start: Some(1.0),
207 derivative: None,
208 reinit: None
209 })
210 );
211 }
212}