Skip to main content

ifc_material/usage/
assignment.rs

1//! Borrowed `IfcRelAssociatesMaterial` projection.
2
3use ifc_model::EntityId;
4
5use crate::view::{
6    borrowed_entity, optional_text, required_ref, required_refs, required_text, MaterialView,
7};
8use crate::MaterialResult;
9
10borrowed_entity!(MaterialAssignment, "IFCRELASSOCIATESMATERIAL");
11
12impl<'m> MaterialAssignment<'m> {
13    /// `IfcRelAssociatesMaterial.GlobalId`. Required.
14    pub fn global_id(self) -> MaterialResult<&'m str> {
15        required_text(
16            "IFCRELASSOCIATESMATERIAL",
17            self.id(),
18            self.entity(),
19            self.slot("GlobalId")?,
20            "GlobalId",
21        )
22    }
23
24    /// `IfcRelAssociatesMaterial.Name`, if given.
25    pub fn name(self) -> MaterialResult<Option<&'m str>> {
26        optional_text(
27            "IFCRELASSOCIATESMATERIAL",
28            self.id(),
29            self.entity(),
30            self.slot("Name")?,
31            "Name",
32        )
33    }
34
35    /// `IfcRelAssociatesMaterial.Description`, if given.
36    pub fn description(self) -> MaterialResult<Option<&'m str>> {
37        optional_text(
38            "IFCRELASSOCIATESMATERIAL",
39            self.id(),
40            self.entity(),
41            self.slot("Description")?,
42            "Description",
43        )
44    }
45
46    /// `IfcRelAssociatesMaterial.RelatedObjects`. Required and must be
47    /// non-empty.
48    pub fn related_object_ids(self) -> MaterialResult<Vec<EntityId>> {
49        required_refs(
50            "IFCRELASSOCIATESMATERIAL",
51            self.id(),
52            self.entity(),
53            self.slot("RelatedObjects")?,
54            "RelatedObjects",
55            1,
56        )
57    }
58
59    /// `IfcRelAssociatesMaterial.RelatingMaterial`, an `IfcMaterialSelect`
60    /// branch reference. Required.
61    pub fn relating_material_id(self) -> MaterialResult<EntityId> {
62        required_ref(
63            "IFCRELASSOCIATESMATERIAL",
64            self.id(),
65            self.entity(),
66            self.slot("RelatingMaterial")?,
67            "RelatingMaterial",
68        )
69    }
70}
71
72impl<'m> MaterialView<'m> {
73    /// Iterates every `IfcRelAssociatesMaterial` instance in the model.
74    pub fn assignments(self) -> impl Iterator<Item = MaterialAssignment<'m>> + 'm {
75        let release = self.release();
76        self.model()
77            .of_type("IFCRELASSOCIATESMATERIAL")
78            .map(move |(id, entity)| MaterialAssignment::from_known(id, entity, release))
79    }
80
81    /// Collects every `IfcRelAssociatesMaterial` whose `RelatedObjects`
82    /// includes `object`. Multiple hits indicate an ambiguous direct
83    /// assignment; callers that need a single answer should check the
84    /// result length themselves or use `assigned_material`.
85    pub fn assignments_for(self, object: EntityId) -> MaterialResult<Vec<MaterialAssignment<'m>>> {
86        let mut matches = Vec::new();
87        for assignment in self.assignments() {
88            if assignment.related_object_ids()?.contains(&object) {
89                matches.push(assignment);
90            }
91        }
92        Ok(matches)
93    }
94}