Skip to main content

ifc_material/material/
relationships.rs

1//! Material lists, classifications, and resource-level relationships.
2//!
3//! `IfcMaterialList` and `IfcMaterialClassificationRelationship` keep their
4//! layout in every release. `IfcMaterialRelationship` is IFC4 onwards; IFC4X3
5//! renamed its `Expression` to `MaterialExpression` at the same position.
6
7use ifc_model::EntityId;
8
9use crate::view::{borrowed_entity, optional_text, required_ref, required_refs, MaterialView};
10use crate::MaterialResult;
11
12borrowed_entity!(
13    MaterialClassificationRelationship,
14    "IFCMATERIALCLASSIFICATIONRELATIONSHIP"
15);
16borrowed_entity!(MaterialList, "IFCMATERIALLIST");
17borrowed_entity!(MaterialRelationship, "IFCMATERIALRELATIONSHIP");
18
19impl MaterialClassificationRelationship<'_> {
20    /// `IfcMaterialClassificationRelationship.MaterialClassifications`.
21    /// Required and must be non-empty.
22    pub fn classification_ids(self) -> MaterialResult<Vec<EntityId>> {
23        required_refs(
24            "IFCMATERIALCLASSIFICATIONRELATIONSHIP",
25            self.id(),
26            self.entity(),
27            self.slot("MaterialClassifications")?,
28            "MaterialClassifications",
29            1,
30        )
31    }
32
33    /// `IfcMaterialClassificationRelationship.ClassifiedMaterial`. Required.
34    pub fn material_id(self) -> MaterialResult<EntityId> {
35        required_ref(
36            "IFCMATERIALCLASSIFICATIONRELATIONSHIP",
37            self.id(),
38            self.entity(),
39            self.slot("ClassifiedMaterial")?,
40            "ClassifiedMaterial",
41        )
42    }
43}
44
45impl MaterialList<'_> {
46    /// `IfcMaterialList.Materials`, the ids of the constituent
47    /// `IfcMaterial` entities. Required and must be non-empty.
48    pub fn material_ids(self) -> MaterialResult<Vec<EntityId>> {
49        required_refs(
50            "IFCMATERIALLIST",
51            self.id(),
52            self.entity(),
53            self.slot("Materials")?,
54            "Materials",
55            1,
56        )
57    }
58}
59
60impl<'m> MaterialRelationship<'m> {
61    /// `IfcMaterialRelationship.Name`, if given.
62    pub fn name(self) -> MaterialResult<Option<&'m str>> {
63        optional_text(
64            "IFCMATERIALRELATIONSHIP",
65            self.id(),
66            self.entity(),
67            self.slot("Name")?,
68            "Name",
69        )
70    }
71
72    /// `IfcMaterialRelationship.Description`, if given.
73    pub fn description(self) -> MaterialResult<Option<&'m str>> {
74        optional_text(
75            "IFCMATERIALRELATIONSHIP",
76            self.id(),
77            self.entity(),
78            self.slot("Description")?,
79            "Description",
80        )
81    }
82
83    /// `IfcMaterialRelationship.RelatingMaterial`. Required.
84    pub fn relating_material_id(self) -> MaterialResult<EntityId> {
85        required_ref(
86            "IFCMATERIALRELATIONSHIP",
87            self.id(),
88            self.entity(),
89            self.slot("RelatingMaterial")?,
90            "RelatingMaterial",
91        )
92    }
93
94    /// `IfcMaterialRelationship.RelatedMaterials`. Required and must be
95    /// non-empty.
96    pub fn related_material_ids(self) -> MaterialResult<Vec<EntityId>> {
97        required_refs(
98            "IFCMATERIALRELATIONSHIP",
99            self.id(),
100            self.entity(),
101            self.slot("RelatedMaterials")?,
102            "RelatedMaterials",
103            1,
104        )
105    }
106
107    /// `IfcMaterialRelationship.Expression` (IFC4X3: `MaterialExpression`),
108    /// if given.
109    pub fn expression(self) -> MaterialResult<Option<&'m str>> {
110        optional_text(
111            "IFCMATERIALRELATIONSHIP",
112            self.id(),
113            self.entity(),
114            self.slot("Expression")?,
115            "Expression",
116        )
117    }
118}
119
120impl<'m> MaterialView<'m> {
121    /// Iterates every `IfcMaterialClassificationRelationship` in the model.
122    pub fn classification_relationships(
123        self,
124    ) -> impl Iterator<Item = MaterialClassificationRelationship<'m>> + 'm {
125        let release = self.release();
126        self.model()
127            .of_type("IFCMATERIALCLASSIFICATIONRELATIONSHIP")
128            .map(move |(id, entity)| {
129                MaterialClassificationRelationship::from_known(id, entity, release)
130            })
131    }
132
133    /// Iterates every `IfcMaterialList` instance in the model.
134    pub fn material_lists(self) -> impl Iterator<Item = MaterialList<'m>> + 'm {
135        let release = self.release();
136        self.model()
137            .of_type("IFCMATERIALLIST")
138            .map(move |(id, entity)| MaterialList::from_known(id, entity, release))
139    }
140
141    /// Iterates every `IfcMaterialRelationship` instance in the model.
142    pub fn material_relationships(self) -> impl Iterator<Item = MaterialRelationship<'m>> + 'm {
143        let release = self.release();
144        self.model()
145            .of_type("IFCMATERIALRELATIONSHIP")
146            .map(move |(id, entity)| MaterialRelationship::from_known(id, entity, release))
147    }
148}