Skip to main content

ifc_material/profile/
definition.rs

1//! `IfcMaterialProfile` semantics and authored offsets.
2
3use ifc_model::EntityId;
4
5use crate::view::{
6    borrowed_entity, optional_integer, optional_ref, optional_text, required_number_array_2,
7    required_ref, MaterialView,
8};
9use crate::{MaterialError, MaterialResult};
10
11borrowed_entity!(MaterialProfile, "IFCMATERIALPROFILE");
12borrowed_entity!(MaterialProfileWithOffsets, "IFCMATERIALPROFILEWITHOFFSETS");
13
14macro_rules! profile_accessors {
15    ($type:ident, $ifc_name:literal) => {
16        impl<'m> $type<'m> {
17            /// `Name`, if given.
18            pub fn name(self) -> MaterialResult<Option<&'m str>> {
19                optional_text($ifc_name, self.id(), self.entity(), 0, "Name")
20            }
21
22            /// `Description`, if given.
23            pub fn description(self) -> MaterialResult<Option<&'m str>> {
24                optional_text($ifc_name, self.id(), self.entity(), 1, "Description")
25            }
26
27            /// `Material`, the associated `IfcMaterial`, if given.
28            pub fn material_id(self) -> MaterialResult<Option<EntityId>> {
29                optional_ref($ifc_name, self.id(), self.entity(), 2, "Material")
30            }
31
32            /// `Profile`, the associated `IfcProfileDef`. Required.
33            pub fn profile_id(self) -> MaterialResult<EntityId> {
34                required_ref($ifc_name, self.id(), self.entity(), 3, "Profile")
35            }
36
37            /// `Priority`, if given. Must be in `0..=100`.
38            pub fn priority(self) -> MaterialResult<Option<i64>> {
39                let value = optional_integer($ifc_name, self.id(), self.entity(), 4, "Priority")?;
40                if value.is_some_and(|value| !(0..=100).contains(&value)) {
41                    return Err(MaterialError::InvalidValue {
42                        entity: $ifc_name,
43                        id: self.id(),
44                        attribute: "Priority",
45                        value: "expected an integer in 0..=100".to_owned(),
46                    });
47                }
48                Ok(value)
49            }
50
51            /// `Category`, if given.
52            pub fn category(self) -> MaterialResult<Option<&'m str>> {
53                optional_text($ifc_name, self.id(), self.entity(), 5, "Category")
54            }
55        }
56    };
57}
58profile_accessors!(MaterialProfile, "IFCMATERIALPROFILE");
59profile_accessors!(MaterialProfileWithOffsets, "IFCMATERIALPROFILEWITHOFFSETS");
60
61impl MaterialProfileWithOffsets<'_> {
62    /// `IfcMaterialProfileWithOffsets.OffsetValues`. Required, a 2-element
63    /// list.
64    pub fn offset_values(self) -> MaterialResult<[f64; 2]> {
65        required_number_array_2(
66            "IFCMATERIALPROFILEWITHOFFSETS",
67            self.id(),
68            self.entity(),
69            6,
70            "OffsetValues",
71        )
72    }
73}
74
75impl<'m> MaterialView<'m> {
76    /// Iterates every `IfcMaterialProfile` instance in the model.
77    pub fn profiles(self) -> impl Iterator<Item = MaterialProfile<'m>> + 'm {
78        self.model()
79            .of_type("IFCMATERIALPROFILE")
80            .map(|(id, entity)| MaterialProfile::from_known(id, entity))
81    }
82
83    /// Iterates every `IfcMaterialProfileWithOffsets` instance in the model.
84    pub fn profiles_with_offsets(
85        self,
86    ) -> impl Iterator<Item = MaterialProfileWithOffsets<'m>> + 'm {
87        self.model()
88            .of_type("IFCMATERIALPROFILEWITHOFFSETS")
89            .map(|(id, entity)| MaterialProfileWithOffsets::from_known(id, entity))
90    }
91}