Skip to main content

fmi_schema/fmi3/
build_description.rs

1//! FMI 3.0 Build Description XML Schema
2//!
3//! This module provides Rust data structures for parsing and generating
4//! FMI 3.0 Build Description XML files (`buildDescription.xml`).
5//!
6//! The Build Description XML file contains information about how to compile
7//! the source code of an FMU, including:
8//! - Source files and compilation settings
9//! - Preprocessor definitions
10//! - Include directories
11//! - Library dependencies
12//! - Platform-specific configurations
13//!
14//! # Example
15//!
16//! ```rust
17//! use fmi_schema::fmi3::{Fmi3BuildDescription, BuildConfiguration, SourceFileSet, SourceFile};
18//!
19//! // Parse a build description from XML
20//! let xml = r#"<?xml version="1.0" encoding="UTF-8"?>
21//! <fmiBuildDescription fmiVersion="3.0">
22//!     <BuildConfiguration modelIdentifier="MyModel" platform="linux64">
23//!         <SourceFileSet language="C" compiler="gcc">
24//!             <SourceFile name="src/model.c"/>
25//!         </SourceFileSet>
26//!     </BuildConfiguration>
27//! </fmiBuildDescription>"#;
28//!
29//! let build_desc: Fmi3BuildDescription = fmi_schema::deserialize(xml).unwrap();
30//! assert_eq!(build_desc.fmi_version, "3.0");
31//! assert_eq!(build_desc.build_configurations.len(), 1);
32//! ```
33
34use super::Annotations;
35
36/// Root element for FMI 3.0 build description XML
37#[derive(Default, Debug, PartialEq, hard_xml::XmlRead, hard_xml::XmlWrite)]
38#[xml(
39    tag = "fmiBuildDescription",
40    strict(unknown_attribute, unknown_element)
41)]
42pub struct Fmi3BuildDescription {
43    /// Version of FMI that was used to generate the XML file.
44    /// Must match the pattern 3[.](0|[1-9][0-9]*)([.](0|[1-9][0-9]*))?(-.+)?
45    #[xml(attr = "fmiVersion")]
46    pub fmi_version: String,
47
48    /// Build configurations for different platforms and settings
49    #[xml(child = "BuildConfiguration")]
50    pub build_configurations: Vec<BuildConfiguration>,
51
52    /// Optional annotations
53    #[xml(child = "Annotations")]
54    pub annotations: Option<Annotations>,
55}
56
57/// Build configuration for a specific platform and model identifier
58#[derive(Default, Debug, PartialEq, hard_xml::XmlRead, hard_xml::XmlWrite)]
59#[xml(tag = "BuildConfiguration", strict(unknown_attribute, unknown_element))]
60pub struct BuildConfiguration {
61    /// Model identifier that this build configuration applies to
62    #[xml(attr = "modelIdentifier")]
63    pub model_identifier: String,
64
65    /// Target platform (e.g., "linux64", "win32", "darwin64")
66    #[xml(attr = "platform")]
67    pub platform: Option<String>,
68
69    /// Optional description of this build configuration
70    #[xml(attr = "description")]
71    pub description: Option<String>,
72
73    /// Source file sets for compilation
74    #[xml(child = "SourceFileSet")]
75    pub source_file_sets: Vec<SourceFileSet>,
76
77    /// External libraries to link against
78    #[xml(child = "Library")]
79    pub libraries: Vec<Library>,
80
81    /// Optional annotations
82    #[xml(child = "Annotations")]
83    pub annotations: Option<Annotations>,
84}
85
86/// Set of source files with compilation settings
87#[derive(Default, Debug, PartialEq, hard_xml::XmlRead, hard_xml::XmlWrite)]
88#[xml(tag = "SourceFileSet", strict(unknown_attribute, unknown_element))]
89pub struct SourceFileSet {
90    /// Optional name for this source file set
91    #[xml(attr = "name")]
92    pub name: Option<String>,
93
94    /// Programming language (e.g., "C", "C++", "Fortran")
95    #[xml(attr = "language")]
96    pub language: Option<String>,
97
98    /// Compiler to use (e.g., "gcc", "clang", "msvc")
99    #[xml(attr = "compiler")]
100    pub compiler: Option<String>,
101
102    /// Additional compiler options
103    #[xml(attr = "compilerOptions")]
104    pub compiler_options: Option<String>,
105
106    /// List of source files in this set
107    #[xml(child = "SourceFile")]
108    pub source_files: Vec<SourceFile>,
109
110    /// Preprocessor definitions
111    #[xml(child = "PreprocessorDefinition")]
112    pub preprocessor_definitions: Vec<PreprocessorDefinition>,
113
114    /// Include directories
115    #[xml(child = "IncludeDirectory")]
116    pub include_directories: Vec<IncludeDirectory>,
117
118    /// Optional annotations
119    #[xml(child = "Annotations")]
120    pub annotations: Option<Annotations>,
121}
122
123/// Individual source file
124#[derive(Default, Debug, PartialEq, hard_xml::XmlRead, hard_xml::XmlWrite)]
125#[xml(tag = "SourceFile", strict(unknown_attribute, unknown_element))]
126pub struct SourceFile {
127    /// Name/path of the source file
128    #[xml(attr = "name")]
129    pub name: String,
130
131    /// Optional annotations
132    #[xml(child = "Annotations")]
133    pub annotations: Option<Annotations>,
134}
135
136/// Preprocessor definition/macro
137#[derive(Default, Debug, PartialEq, hard_xml::XmlRead, hard_xml::XmlWrite)]
138#[xml(
139    tag = "PreprocessorDefinition",
140    strict(unknown_attribute, unknown_element)
141)]
142pub struct PreprocessorDefinition {
143    /// Name of the preprocessor definition
144    #[xml(attr = "name")]
145    pub name: String,
146
147    /// Whether this definition is optional
148    #[xml(attr = "optional")]
149    pub optional: Option<bool>,
150
151    /// Value of the preprocessor definition
152    #[xml(attr = "value")]
153    pub value: Option<String>,
154
155    /// Description of this preprocessor definition
156    #[xml(attr = "description")]
157    pub description: Option<String>,
158
159    /// Possible option values
160    #[xml(child = "Option")]
161    pub options: Vec<PreprocessorOption>,
162
163    /// Optional annotations
164    #[xml(child = "Annotations")]
165    pub annotations: Option<Annotations>,
166}
167
168/// Option for a preprocessor definition
169#[derive(Default, Debug, PartialEq, hard_xml::XmlRead, hard_xml::XmlWrite)]
170#[xml(tag = "Option", strict(unknown_attribute, unknown_element))]
171pub struct PreprocessorOption {
172    /// Value of the option
173    #[xml(attr = "value")]
174    pub value: Option<String>,
175
176    /// Description of the option
177    #[xml(attr = "description")]
178    pub description: Option<String>,
179}
180
181/// Include directory for compilation
182#[derive(Default, Debug, PartialEq, hard_xml::XmlRead, hard_xml::XmlWrite)]
183#[xml(tag = "IncludeDirectory", strict(unknown_attribute, unknown_element))]
184pub struct IncludeDirectory {
185    /// Name/path of the include directory
186    #[xml(attr = "name")]
187    pub name: String,
188
189    /// Optional annotations
190    #[xml(child = "Annotations")]
191    pub annotations: Option<Annotations>,
192}
193
194/// External library dependency
195#[derive(Default, Debug, PartialEq, hard_xml::XmlRead, hard_xml::XmlWrite)]
196#[xml(tag = "Library", strict(unknown_attribute, unknown_element))]
197pub struct Library {
198    /// Name of the library
199    #[xml(attr = "name")]
200    pub name: String,
201
202    /// Version of the library
203    #[xml(attr = "version")]
204    pub version: Option<String>,
205
206    /// Whether this is an external library (not part of the FMU)
207    #[xml(attr = "external")]
208    pub external: Option<bool>,
209
210    /// Description of the library
211    #[xml(attr = "description")]
212    pub description: Option<String>,
213
214    /// Optional annotations
215    #[xml(child = "Annotations")]
216    pub annotations: Option<Annotations>,
217}