Skip to main content

ifc_material/constituent/
definition.rs

1//! `IfcMaterialConstituent` semantics.
2
3use ifc_model::EntityId;
4
5use crate::view::{borrowed_entity, optional_number, optional_text, required_ref, MaterialView};
6use crate::{MaterialError, MaterialResult};
7
8borrowed_entity!(MaterialConstituent, "IFCMATERIALCONSTITUENT");
9
10impl<'m> MaterialConstituent<'m> {
11    /// `IfcMaterialConstituent.Name`, if given.
12    pub fn name(self) -> MaterialResult<Option<&'m str>> {
13        optional_text(
14            "IFCMATERIALCONSTITUENT",
15            self.id(),
16            self.entity(),
17            0,
18            "Name",
19        )
20    }
21
22    /// `IfcMaterialConstituent.Description`, if given.
23    pub fn description(self) -> MaterialResult<Option<&'m str>> {
24        optional_text(
25            "IFCMATERIALCONSTITUENT",
26            self.id(),
27            self.entity(),
28            1,
29            "Description",
30        )
31    }
32
33    /// `IfcMaterialConstituent.Material`. Required.
34    pub fn material_id(self) -> MaterialResult<EntityId> {
35        required_ref(
36            "IFCMATERIALCONSTITUENT",
37            self.id(),
38            self.entity(),
39            2,
40            "Material",
41        )
42    }
43
44    /// `IfcMaterialConstituent.Fraction`, if given. Must be in `0.0..=1.0`
45    /// when present.
46    pub fn fraction(self) -> MaterialResult<Option<f64>> {
47        let value = optional_number(
48            "IFCMATERIALCONSTITUENT",
49            self.id(),
50            self.entity(),
51            3,
52            "Fraction",
53        )?;
54        if value.is_some_and(|value| !(0.0..=1.0).contains(&value)) {
55            return Err(MaterialError::InvalidValue {
56                entity: "IFCMATERIALCONSTITUENT",
57                id: self.id(),
58                attribute: "Fraction",
59                value: "expected a normalized ratio in 0..=1".to_owned(),
60            });
61        }
62        Ok(value)
63    }
64
65    /// `IfcMaterialConstituent.Category`, if given.
66    pub fn category(self) -> MaterialResult<Option<&'m str>> {
67        optional_text(
68            "IFCMATERIALCONSTITUENT",
69            self.id(),
70            self.entity(),
71            4,
72            "Category",
73        )
74    }
75}
76
77impl<'m> MaterialView<'m> {
78    /// Iterates every `IfcMaterialConstituent` instance in the model.
79    pub fn constituents(self) -> impl Iterator<Item = MaterialConstituent<'m>> + 'm {
80        self.model()
81            .of_type("IFCMATERIALCONSTITUENT")
82            .map(|(id, entity)| MaterialConstituent::from_known(id, entity))
83    }
84}