Skip to main content

openbim_mmc/
model.rs

1use uuid::Uuid;
2
3/// One extensible metadata item from an MMC `MetaData` collection.
4#[derive(Debug, Clone, Default, PartialEq, Eq)]
5pub struct MetadataEntry {
6    pub key: String,
7    pub value: String,
8    pub value_type: Option<String>,
9    pub category: Option<String>,
10}
11
12/// Metadata carried by the MMC `MultiModel` root.
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct ContainerMetadata {
15    pub uuid: Uuid,
16    pub format_version: String,
17    pub mm_domain: Option<String>,
18    pub metadata: Vec<MetadataEntry>,
19}
20
21impl Default for ContainerMetadata {
22    fn default() -> Self {
23        Self {
24            uuid: Uuid::nil(),
25            format_version: "2.0.0".to_owned(),
26            mm_domain: None,
27            metadata: Vec::new(),
28        }
29    }
30}
31
32/// An embedded relative archive path or a container-external absolute IRI.
33#[derive(Debug, Clone, PartialEq, Eq)]
34pub enum ResourceLocation {
35    Embedded(String),
36    External(String),
37}
38
39impl Default for ResourceLocation {
40    fn default() -> Self {
41        Self::Embedded(String::new())
42    }
43}
44
45impl ResourceLocation {
46    #[must_use]
47    pub fn embedded_path(&self) -> Option<&str> {
48        match self {
49            Self::Embedded(path) => Some(path),
50            Self::External(_) => None,
51        }
52    }
53
54    #[must_use]
55    pub fn external_uri(&self) -> Option<&str> {
56        match self {
57            Self::External(uri) => Some(uri),
58            Self::Embedded(_) => None,
59        }
60    }
61}
62
63/// One physical data resource for a representation of an application model.
64#[derive(Debug, Clone, Default, PartialEq, Eq)]
65pub struct DataResource {
66    pub id: String,
67    pub location: ResourceLocation,
68    pub metadata: Vec<MetadataEntry>,
69}
70
71/// One data-format representation of an application model.
72#[derive(Debug, Clone, Default, PartialEq, Eq)]
73pub struct ModelData {
74    pub id: String,
75    pub format_type: String,
76    pub format_version: Option<String>,
77    pub metadata: Vec<MetadataEntry>,
78    pub resources: Vec<DataResource>,
79}
80
81/// Typed projection of an MMC application-model declaration.
82#[derive(Debug, Clone, Default, PartialEq, Eq)]
83pub struct ApplicationModel {
84    pub id: String,
85    pub model_type: String,
86    pub metadata: Vec<MetadataEntry>,
87    pub representations: Vec<ModelData>,
88}
89
90/// Reference to an external or bundled LinkModel XML document.
91#[derive(Debug, Clone, Default, PartialEq, Eq)]
92pub struct LinkModelReference {
93    pub location: ResourceLocation,
94    pub linked_models: Vec<String>,
95    pub metadata: Vec<MetadataEntry>,
96}
97
98/// Lossless source plus typed MMC container projection.
99#[derive(Debug, Clone, PartialEq, Eq)]
100pub struct MultiModel {
101    pub metadata: ContainerMetadata,
102    pub models: Vec<ApplicationModel>,
103    pub link_models: Vec<LinkModelReference>,
104    pub(crate) source: Vec<u8>,
105}
106
107impl MultiModel {
108    #[must_use]
109    pub fn source_bytes(&self) -> &[u8] {
110        &self.source
111    }
112}
113
114/// Optional weight or qualification attached to one relatum.
115#[derive(Debug, Clone, Default, PartialEq, Eq)]
116pub struct Rate {
117    pub rate_type: String,
118    pub value: String,
119    pub target_model: String,
120}
121
122/// One application-model element participating in an n-ary link.
123#[derive(Debug, Clone, Default, PartialEq, Eq)]
124pub struct Relatum {
125    pub element_id: String,
126    pub model_id: String,
127    pub format_id: Option<String>,
128    pub resource_id: Option<String>,
129    pub metadata: Vec<MetadataEntry>,
130    pub rates: Vec<Rate>,
131}
132
133/// One n-ary relation between elements from at least two application models.
134#[derive(Debug, Clone, Default, PartialEq, Eq)]
135pub struct Link {
136    pub metadata: Vec<MetadataEntry>,
137    pub relata: Vec<Relatum>,
138}
139
140/// Typed projection of one MMC 2.0 LinkModel XML document.
141#[derive(Debug, Clone, PartialEq, Eq)]
142pub struct LinkModel {
143    pub format_version: String,
144    pub metadata: Vec<MetadataEntry>,
145    pub links: Vec<Link>,
146}
147
148impl Default for LinkModel {
149    fn default() -> Self {
150        Self {
151            format_version: "2.0.0".to_owned(),
152            metadata: Vec::new(),
153            links: Vec::new(),
154        }
155    }
156}
157
158/// A parsed LinkModel tied to its exact archive source entry.
159#[derive(Debug, Clone, PartialEq, Eq)]
160pub struct LinkModelDocument {
161    pub(crate) path: String,
162    pub(crate) source: Vec<u8>,
163    pub(crate) model: LinkModel,
164}
165
166impl LinkModelDocument {
167    #[must_use]
168    pub fn path(&self) -> &str {
169        &self.path
170    }
171
172    #[must_use]
173    pub fn source_bytes(&self) -> &[u8] {
174        &self.source
175    }
176
177    #[must_use]
178    pub const fn model(&self) -> &LinkModel {
179        &self.model
180    }
181}