Skip to main content

fmi_schema/fmi3/
type.rs

1use super::annotation::Fmi3Annotations;
2
3pub trait BaseTypeTrait {
4    fn name(&self) -> &str;
5    fn description(&self) -> Option<&str>;
6}
7
8macro_rules! declare_float_type {
9    ($name: ident, $tag: expr, $type: ty) => {
10        #[derive(Default, PartialEq, Debug, hard_xml::XmlRead, hard_xml::XmlWrite)]
11        #[xml(tag = $tag, strict(unknown_attribute, unknown_element))]
12        pub struct $name {
13            // TypeDefinitionBase
14            #[xml(attr = "name")]
15            pub name: String,
16            #[xml(attr = "description")]
17            pub description: Option<String>,
18            #[xml(child = "Annotations")]
19            pub annotations: Option<Fmi3Annotations>,
20            // RealBaseAttributes
21            #[xml(attr = "quantity")]
22            pub quantity: Option<String>,
23            #[xml(attr = "unit")]
24            pub unit: Option<String>,
25            #[xml(attr = "displayUnit")]
26            pub display_unit: Option<String>,
27            #[xml(attr = "relativeQuantity")]
28            pub relative_quantity: Option<bool>,
29            #[xml(attr = "unbounded")]
30            pub unbounded: Option<bool>,
31            // FloatAttributes
32            #[xml(attr = "min")]
33            pub min: Option<$type>,
34            #[xml(attr = "max")]
35            pub max: Option<$type>,
36            #[xml(attr = "nominal")]
37            pub nominal: Option<$type>,
38        }
39
40        impl BaseTypeTrait for $name {
41            fn name(&self) -> &str {
42                &self.name
43            }
44
45            fn description(&self) -> Option<&str> {
46                self.description.as_deref()
47            }
48        }
49    };
50}
51
52macro_rules! declare_int_type {
53    ($name: ident, $tag: expr, $type: ty) => {
54        #[derive(Default, PartialEq, Debug, hard_xml::XmlRead, hard_xml::XmlWrite)]
55        #[xml(tag = $tag, strict(unknown_attribute, unknown_element))]
56        pub struct $name {
57            // TypeDefinitionBase
58            #[xml(attr = "name")]
59            pub name: String,
60            #[xml(attr = "description")]
61            pub description: Option<String>,
62            #[xml(child = "Annotations")]
63            pub annotations: Option<Fmi3Annotations>,
64            // IntegerBaseAttributes
65            #[xml(attr = "quantity")]
66            quantity: Option<String>,
67            // IntAttributes
68            #[xml(attr = "min")]
69            pub min: Option<$type>,
70            #[xml(attr = "max")]
71            pub max: Option<$type>,
72        }
73    };
74}
75
76declare_float_type!(Float32Type, "Float32Type", f32);
77declare_float_type!(Float64Type, "Float64Type", f64);
78declare_int_type!(Int8Type, "Int8Type", i8);
79declare_int_type!(UInt8Type, "UInt8Type", u8);
80declare_int_type!(Int16Type, "Int16Type", i16);
81declare_int_type!(UInt16Type, "UInt16Type", u16);
82declare_int_type!(Int32Type, "Int32Type", i32);
83declare_int_type!(UInt32Type, "UInt32Type", u32);
84declare_int_type!(Int64Type, "Int64Type", i64);
85declare_int_type!(UInt64Type, "UInt64Type", u64);
86
87#[derive(Default, PartialEq, Debug, hard_xml::XmlRead, hard_xml::XmlWrite)]
88#[xml(tag = "BooleanType", strict(unknown_attribute, unknown_element))]
89pub struct BooleanType {
90    // TypeDefinitionBase
91    #[xml(attr = "name")]
92    pub name: String,
93    #[xml(attr = "description")]
94    pub description: Option<String>,
95    #[xml(child = "Annotations")]
96    pub annotations: Option<Fmi3Annotations>,
97}
98
99#[derive(Default, PartialEq, Debug, hard_xml::XmlRead, hard_xml::XmlWrite)]
100#[xml(tag = "StringType", strict(unknown_attribute, unknown_element))]
101pub struct StringType {
102    // TypeDefinitionBase
103    #[xml(attr = "name")]
104    pub name: String,
105    #[xml(attr = "description")]
106    pub description: Option<String>,
107    #[xml(child = "Annotations")]
108    pub annotations: Option<Fmi3Annotations>,
109}
110
111#[derive(Default, PartialEq, Debug, hard_xml::XmlRead, hard_xml::XmlWrite)]
112#[xml(tag = "BinaryType", strict(unknown_attribute, unknown_element))]
113pub struct BinaryType {
114    // TypeDefinitionBase
115    #[xml(attr = "name")]
116    pub name: String,
117    #[xml(attr = "description")]
118    pub description: Option<String>,
119    #[xml(child = "Annotations")]
120    pub annotations: Option<Fmi3Annotations>,
121    // BinaryType specific attributes
122    #[xml(attr = "mimeType")]
123    pub mime_type: Option<String>,
124    #[xml(attr = "maxSize")]
125    pub max_size: Option<u64>,
126}
127
128#[derive(PartialEq, Debug, hard_xml::XmlRead, hard_xml::XmlWrite)]
129#[xml(tag = "Item", strict(unknown_attribute, unknown_element))]
130pub struct EnumerationItem {
131    #[xml(attr = "name")]
132    pub name: String,
133    #[xml(attr = "value")]
134    pub value: i64,
135    #[xml(attr = "description")]
136    pub description: Option<String>,
137    #[xml(child = "Annotations")]
138    pub annotations: Option<Fmi3Annotations>,
139}
140
141#[derive(PartialEq, Debug, hard_xml::XmlRead, hard_xml::XmlWrite)]
142#[xml(tag = "EnumerationType", strict(unknown_attribute, unknown_element))]
143pub struct EnumerationType {
144    // TypeDefinitionBase
145    #[xml(attr = "name")]
146    pub name: String,
147    #[xml(attr = "description")]
148    pub description: Option<String>,
149    #[xml(child = "Annotations")]
150    pub annotations: Option<Fmi3Annotations>,
151    // IntegerBaseAttributes
152    #[xml(attr = "quantity")]
153    pub quantity: Option<String>,
154    // Items
155    #[xml(child = "Item")]
156    pub items: Vec<EnumerationItem>,
157}
158
159#[derive(Default, PartialEq, Debug, hard_xml::XmlRead, hard_xml::XmlWrite)]
160#[xml(tag = "ClockType", strict(unknown_attribute, unknown_element))]
161pub struct ClockType {
162    // TypeDefinitionBase
163    #[xml(attr = "name")]
164    pub name: String,
165    #[xml(attr = "description")]
166    pub description: Option<String>,
167    #[xml(child = "Annotations")]
168    pub annotations: Option<Fmi3Annotations>,
169    // ClockAttributes
170    #[xml(attr = "canBeDeactivated")]
171    pub can_be_deactivated: Option<bool>,
172    #[xml(attr = "priority")]
173    pub priority: Option<u32>,
174    #[xml(attr = "intervalVariability")]
175    pub interval_variability: Option<String>,
176    #[xml(attr = "intervalDecimal")]
177    pub interval_decimal: Option<f64>,
178    #[xml(attr = "shiftDecimal")]
179    pub shift_decimal: Option<f64>,
180    #[xml(attr = "supportsFraction")]
181    pub supports_fraction: Option<bool>,
182    #[xml(attr = "resolution")]
183    pub resolution: Option<u64>,
184    #[xml(attr = "intervalCounter")]
185    pub interval_counter: Option<u64>,
186    #[xml(attr = "shiftCounter")]
187    pub shift_counter: Option<u64>,
188}
189
190#[derive(PartialEq, Debug, hard_xml::XmlRead, hard_xml::XmlWrite)]
191pub enum TypeDefinition {
192    #[xml(tag = "Float32Type")]
193    Float32(Float32Type),
194    #[xml(tag = "Float64Type")]
195    Float64(Float64Type),
196    #[xml(tag = "Int8Type")]
197    Int8(Int8Type),
198    #[xml(tag = "UInt8Type")]
199    UInt8(UInt8Type),
200    #[xml(tag = "Int16Type")]
201    Int16(Int16Type),
202    #[xml(tag = "UInt16Type")]
203    UInt16(UInt16Type),
204    #[xml(tag = "Int32Type")]
205    Int32(Int32Type),
206    #[xml(tag = "UInt32Type")]
207    UInt32(UInt32Type),
208    #[xml(tag = "Int64Type")]
209    Int64(Int64Type),
210    #[xml(tag = "UInt64Type")]
211    UInt64(UInt64Type),
212    #[xml(tag = "BooleanType")]
213    Boolean(BooleanType),
214    #[xml(tag = "StringType")]
215    String(StringType),
216    #[xml(tag = "BinaryType")]
217    Binary(BinaryType),
218    #[xml(tag = "EnumerationType")]
219    Enumeration(EnumerationType),
220    #[xml(tag = "ClockType")]
221    Clock(ClockType),
222}
223
224#[derive(Default, PartialEq, Debug, hard_xml::XmlRead, hard_xml::XmlWrite)]
225#[xml(tag = "TypeDefinitions", strict(unknown_attribute, unknown_element))]
226pub struct TypeDefinitions {
227    #[xml(
228        child = "Float32Type",
229        child = "Float64Type",
230        child = "Int8Type",
231        child = "UInt8Type",
232        child = "Int16Type",
233        child = "UInt16Type",
234        child = "Int32Type",
235        child = "UInt32Type",
236        child = "Int64Type",
237        child = "UInt64Type",
238        child = "BooleanType",
239        child = "StringType",
240        child = "BinaryType",
241        child = "EnumerationType",
242        child = "ClockType"
243    )]
244    pub type_definitions: Vec<TypeDefinition>,
245}
246
247#[test]
248fn test_type_definitions() {
249    let xml = r#"<TypeDefinitions>
250        <Float32Type name="speed" unit="m/s" min="0.0" max="100.0" nominal="50.0"/>
251        <Int16Type name="count" quantity="count" min="0" max="1000"/>
252        <Float64Type name="Position" quantity="Position" unit="m"/>
253    </TypeDefinitions>"#;
254
255    let types: TypeDefinitions = hard_xml::XmlRead::from_str(xml).unwrap();
256    assert_eq!(types.type_definitions.len(), 3);
257}