1use std::{fmt::Display, str::FromStr};
2
3use crate::utils::AttrList;
4
5use super::Annotations;
6
7#[derive(Default, PartialEq, Debug)]
8pub enum DependenciesKind {
9 #[default]
10 Dependent,
11 Constant,
12 Fixed,
13 Tunable,
14 Discrete,
15}
16
17impl FromStr for DependenciesKind {
18 type Err = String;
19
20 fn from_str(s: &str) -> Result<Self, Self::Err> {
21 match s {
22 "dependent" => Ok(DependenciesKind::Dependent),
23 "constant" => Ok(DependenciesKind::Constant),
24 "fixed" => Ok(DependenciesKind::Fixed),
25 "tunable" => Ok(DependenciesKind::Tunable),
26 "discrete" => Ok(DependenciesKind::Discrete),
27 _ => Err(format!("Invalid DependenciesKind: {}", s)),
28 }
29 }
30}
31
32impl Display for DependenciesKind {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 let s = match self {
35 DependenciesKind::Dependent => "dependent",
36 DependenciesKind::Constant => "constant",
37 DependenciesKind::Fixed => "fixed",
38 DependenciesKind::Tunable => "tunable",
39 DependenciesKind::Discrete => "discrete",
40 };
41 write!(f, "{}", s)
42 }
43}
44
45#[derive(Default, PartialEq, Debug)]
46pub struct Fmi3Unknown {
47 pub annotations: Option<Annotations>,
48 pub value_reference: u32,
49 pub dependencies: Option<AttrList<u32>>,
50 pub dependencies_kind: Option<AttrList<DependenciesKind>>,
51}
52
53impl<'__input> ::hard_xml::XmlRead<'__input> for Fmi3Unknown {
54 fn from_reader(reader: &mut ::hard_xml::XmlReader<'__input>) -> ::hard_xml::XmlResult<Self> {
55 use ::hard_xml::XmlError;
56 use ::hard_xml::xmlparser::{ElementEnd, Token};
57 ::hard_xml::log_start_reading!(Fmi3Unknown_);
58 let mut __self_annotations = None;
59 let mut __self_value_reference = None;
60 let mut __self_dependencies = None;
61 let mut __self_dependencies_kind = None;
62
63 let tag = reader
64 .find_element_start(None)?
65 .expect("Expected start element");
66 let _ = reader.next().unwrap()?; while let Some((__key, __value)) = reader.find_attribute()? {
69 match __key {
70 "valueReference" => {
71 ::hard_xml::log_start_reading_field!(Fmi3Unknown_, value_reference);
72 if __self_value_reference.is_some() {
73 return ::std::result::Result::Err(
74 ::hard_xml::XmlExtendedError::DuplicateAttribute(
75 ("valueReference").into(),
76 )
77 .into(),
78 );
79 }
80 __self_value_reference = Some(
81 <u32 as std::str::FromStr>::from_str(&__value)
82 .map_err(|e| XmlError::FromStr(e.into()))?,
83 );
84 ::hard_xml::log_finish_reading_field!(Fmi3Unknown_, value_reference);
85 }
86 "dependencies" => {
87 ::hard_xml::log_start_reading_field!(Fmi3Unknown_, dependencies);
88 if __self_dependencies.is_some() {
89 return ::std::result::Result::Err(
90 ::hard_xml::XmlExtendedError::DuplicateAttribute(
91 ("dependencies").into(),
92 )
93 .into(),
94 );
95 }
96 __self_dependencies = Some(
97 <AttrList<u32> as std::str::FromStr>::from_str(&__value)
98 .map_err(|e| XmlError::FromStr(e.into()))?,
99 );
100 ::hard_xml::log_finish_reading_field!(Fmi3Unknown_, dependencies);
101 }
102 "dependenciesKind" => {
103 ::hard_xml::log_start_reading_field!(Fmi3Unknown_, dependencies_kind);
104 if __self_dependencies_kind.is_some() {
105 return ::std::result::Result::Err(
106 ::hard_xml::XmlExtendedError::DuplicateAttribute(
107 ("dependenciesKind").into(),
108 )
109 .into(),
110 );
111 }
112 __self_dependencies_kind = Some(
113 <AttrList<DependenciesKind> as std::str::FromStr>::from_str(&__value)
114 .map_err(|e| XmlError::FromStr(e.into()))?,
115 );
116 ::hard_xml::log_finish_reading_field!(Fmi3Unknown_, dependencies_kind);
117 }
118 key => {
119 return Err(XmlError::UnknownField {
120 name: stringify!(Fmi3Unknown_).to_owned(),
121 field: key.to_owned(),
122 });
123 }
124 }
125 }
126 if let Token::ElementEnd {
127 end: ElementEnd::Empty,
128 ..
129 } = reader.next().unwrap()?
130 {
131 let __res = Fmi3Unknown {
132 annotations: __self_annotations,
133 value_reference: __self_value_reference.ok_or(XmlError::MissingField {
134 name: stringify!(Fmi3Unknown_).to_owned(),
135 field: stringify!(value_reference).to_owned(),
136 })?,
137 dependencies: __self_dependencies,
138 dependencies_kind: __self_dependencies_kind,
139 };
140 ::hard_xml::log_finish_reading!(Fmi3Unknown_);
141 return Ok(__res);
142 }
143 while let Some(__tag) = reader.find_element_start(Some(tag))? {
144 match __tag {
145 "Annotations" => {
146 ::hard_xml::log_start_reading_field!(Fmi3Unknown_, annotations);
147 if __self_annotations.is_some() {
148 return ::std::result::Result::Err(
149 ::hard_xml::XmlExtendedError::DuplicateElement(
150 __tag.to_string().into(),
151 )
152 .into(),
153 );
154 }
155 __self_annotations =
156 Some(<Annotations as ::hard_xml::XmlRead>::from_reader(reader)?);
157 ::hard_xml::log_finish_reading_field!(Fmi3Unknown_, annotations);
158 }
159 tag => {
160 return Err(XmlError::UnknownField {
161 name: stringify!(Fmi3Unknown_).to_owned(),
162 field: tag.to_owned(),
163 });
164 }
165 }
166 }
167 let __res = Fmi3Unknown {
168 annotations: __self_annotations,
169 value_reference: __self_value_reference.ok_or(XmlError::MissingField {
170 name: stringify!(Fmi3Unknown_).to_owned(),
171 field: stringify!(value_reference).to_owned(),
172 })?,
173 dependencies: __self_dependencies,
174 dependencies_kind: __self_dependencies_kind,
175 };
176 ::hard_xml::log_finish_reading!(Fmi3Unknown_);
177 Ok(__res)
178 }
179}
180
181impl Fmi3Unknown {
182 fn to_writer_with_tag<W: std::io::Write>(
184 &self,
185 writer: &mut ::hard_xml::XmlWriter<W>,
186 tag: &str,
187 ) -> ::hard_xml::XmlResult<()> {
188 let Fmi3Unknown {
189 annotations: __self_annotations,
190 value_reference: __self_value_reference,
191 dependencies: __self_dependencies,
192 dependencies_kind: __self_dependencies_kind,
193 } = self;
194 ::hard_xml::log_start_writing!(Fmi3Unknown);
195 writer.write_element_start(tag)?;
196 ::hard_xml::log_start_writing_field!(Fmi3Unknown, __self_value_reference);
197 let __value = __self_value_reference;
198 writer.write_attribute("valueReference", &format!("{}", __value))?;
199 ::hard_xml::log_finish_writing_field!(Fmi3Unknown, __self_value_reference);
200 ::hard_xml::log_start_writing_field!(Fmi3Unknown, __self_dependencies);
201 if let Some(__value) = __self_dependencies {
202 writer.write_attribute("dependencies", &format!("{}", __value))?;
203 }
204 ::hard_xml::log_finish_writing_field!(Fmi3Unknown, __self_dependencies);
205 ::hard_xml::log_start_writing_field!(Fmi3Unknown, __self_dependencies_kind);
206 if let Some(__value) = __self_dependencies_kind {
207 writer.write_attribute("dependenciesKind", &format!("{}", __value))?;
208 }
209 ::hard_xml::log_finish_writing_field!(Fmi3Unknown, __self_dependencies_kind);
210 if __self_annotations.is_none() {
211 writer.write_element_end_empty()?;
212 } else {
213 writer.write_element_end_open()?;
214 ::hard_xml::log_start_writing_field!(Fmi3Unknown, __self_annotations);
215 if let Some(ele) = __self_annotations {
216 hard_xml::XmlWrite::to_writer(ele, writer)?;
217 }
218 ::hard_xml::log_finish_writing_field!(Fmi3Unknown, __self_annotations);
219 writer.write_element_end_close(tag)?;
220 }
221 ::hard_xml::log_finish_writing!(Fmi3Unknown);
222 Ok(())
223 }
224}
225
226#[derive(PartialEq, Debug, hard_xml::XmlRead)]
227pub enum VariableDependency {
228 #[xml(tag = "Output")]
229 Output(Fmi3Unknown),
230 #[xml(tag = "ContinuousStateDerivative")]
231 ContinuousStateDerivative(Fmi3Unknown),
232 #[xml(tag = "ClockedState")]
233 ClockedState(Fmi3Unknown),
234 #[xml(tag = "InitialUnknown")]
235 InitialUnknown(Fmi3Unknown),
236 #[xml(tag = "EventIndicator")]
237 EventIndicator(Fmi3Unknown),
238}
239
240impl hard_xml::XmlWrite for VariableDependency {
241 fn to_writer<W: std::io::Write>(
242 &self,
243 writer: &mut hard_xml::XmlWriter<W>,
244 ) -> hard_xml::XmlResult<()> {
245 match self {
246 VariableDependency::Output(__inner) => {
247 ::hard_xml::log_start_writing!(VariableDependency::Output);
248 __inner.to_writer_with_tag(writer, "Output")?;
249 ::hard_xml::log_finish_writing!(VariableDependency::Output);
250 }
251 VariableDependency::ContinuousStateDerivative(__inner) => {
252 ::hard_xml::log_start_writing!(VariableDependency::ContinuousStateDerivative);
253 __inner.to_writer_with_tag(writer, "ContinuousStateDerivative")?;
254 ::hard_xml::log_finish_writing!(VariableDependency::ContinuousStateDerivative);
255 }
256 VariableDependency::ClockedState(__inner) => {
257 ::hard_xml::log_start_writing!(VariableDependency::ClockedState);
258 __inner.to_writer_with_tag(writer, "ClockedState")?;
259 ::hard_xml::log_finish_writing!(VariableDependency::ClockedState);
260 }
261 VariableDependency::InitialUnknown(__inner) => {
262 ::hard_xml::log_start_writing!(VariableDependency::InitialUnknown);
263 __inner.to_writer_with_tag(writer, "InitialUnknown")?;
264 ::hard_xml::log_finish_writing!(VariableDependency::InitialUnknown);
265 }
266 VariableDependency::EventIndicator(__inner) => {
267 ::hard_xml::log_start_writing!(VariableDependency::EventIndicator);
268 __inner.to_writer_with_tag(writer, "EventIndicator")?;
269 ::hard_xml::log_finish_writing!(VariableDependency::EventIndicator);
270 }
271 }
272 Ok(())
273 }
274}
275
276#[test]
277fn test_dependencies_kind() {
278 let _ = env_logger::builder()
279 .is_test(true)
280 .format_timestamp(None)
281 .try_init();
282
283 use hard_xml::{XmlRead, XmlWrite};
284 let xml = r#"<Output valueReference="1" dependencies="0 1 2" dependenciesKind="dependent constant fixed"/>"#;
285
286 let var = VariableDependency::from_str(xml).unwrap();
287
288 assert_eq!(
289 var,
290 VariableDependency::Output(Fmi3Unknown {
291 value_reference: 1,
292 dependencies: Some(AttrList(vec![0, 1, 2])),
293 dependencies_kind: Some(AttrList(vec![
294 DependenciesKind::Dependent,
295 DependenciesKind::Constant,
296 DependenciesKind::Fixed
297 ])),
298 ..Default::default()
299 })
300 );
301
302 let xml_out = var.to_string().unwrap();
303 assert_eq!(xml_out, xml);
304}