ifc_material/layer/
definition.rs1use ifc_model::EntityId;
4
5use crate::view::{
6 borrowed_entity, optional_integer, optional_logical, optional_ref, optional_text,
7 required_enum, required_number, required_number_array_2, MaterialView,
8};
9use crate::{LayerSetDirection, LogicalValue, MaterialError, MaterialResult};
10
11borrowed_entity!(MaterialLayer, "IFCMATERIALLAYER");
12borrowed_entity!(MaterialLayerWithOffsets, "IFCMATERIALLAYERWITHOFFSETS");
13
14macro_rules! layer_accessors {
15 ($type:ident, $ifc_name:literal) => {
16 impl<'m> $type<'m> {
17 pub fn material_id(self) -> MaterialResult<Option<EntityId>> {
19 optional_ref($ifc_name, self.id(), self.entity(), 0, "Material")
20 }
21
22 pub fn thickness(self) -> MaterialResult<f64> {
24 let value =
25 required_number($ifc_name, self.id(), self.entity(), 1, "LayerThickness")?;
26 if value < 0.0 {
27 return Err(MaterialError::InvalidValue {
28 entity: $ifc_name,
29 id: self.id(),
30 attribute: "LayerThickness",
31 value: "expected a non-negative length".to_owned(),
32 });
33 }
34 Ok(value)
35 }
36
37 pub fn is_ventilated(self) -> MaterialResult<Option<LogicalValue>> {
39 optional_logical($ifc_name, self.id(), self.entity(), 2, "IsVentilated")
40 }
41
42 pub fn name(self) -> MaterialResult<Option<&'m str>> {
44 optional_text($ifc_name, self.id(), self.entity(), 3, "Name")
45 }
46
47 pub fn description(self) -> MaterialResult<Option<&'m str>> {
49 optional_text($ifc_name, self.id(), self.entity(), 4, "Description")
50 }
51
52 pub fn category(self) -> MaterialResult<Option<&'m str>> {
54 optional_text($ifc_name, self.id(), self.entity(), 5, "Category")
55 }
56
57 pub fn priority(self) -> MaterialResult<Option<i64>> {
59 let value = optional_integer($ifc_name, self.id(), self.entity(), 6, "Priority")?;
60 if value.is_some_and(|value| !(0..=100).contains(&value)) {
61 return Err(MaterialError::InvalidValue {
62 entity: $ifc_name,
63 id: self.id(),
64 attribute: "Priority",
65 value: "expected an integer in 0..=100".to_owned(),
66 });
67 }
68 Ok(value)
69 }
70 }
71 };
72}
73layer_accessors!(MaterialLayer, "IFCMATERIALLAYER");
74layer_accessors!(MaterialLayerWithOffsets, "IFCMATERIALLAYERWITHOFFSETS");
75
76impl MaterialLayerWithOffsets<'_> {
77 pub fn offset_direction(self) -> MaterialResult<LayerSetDirection> {
79 let token = required_enum(
80 "IFCMATERIALLAYERWITHOFFSETS",
81 self.id(),
82 self.entity(),
83 7,
84 "OffsetDirection",
85 )?;
86 LayerSetDirection::parse(token).ok_or_else(|| MaterialError::InvalidValue {
87 entity: "IFCMATERIALLAYERWITHOFFSETS",
88 id: self.id(),
89 attribute: "OffsetDirection",
90 value: token.to_owned(),
91 })
92 }
93
94 pub fn offset_values(self) -> MaterialResult<[f64; 2]> {
97 required_number_array_2(
98 "IFCMATERIALLAYERWITHOFFSETS",
99 self.id(),
100 self.entity(),
101 8,
102 "OffsetValues",
103 )
104 }
105}
106
107impl<'m> MaterialView<'m> {
108 pub fn layers(self) -> impl Iterator<Item = MaterialLayer<'m>> + 'm {
110 self.model()
111 .of_type("IFCMATERIALLAYER")
112 .map(|(id, entity)| MaterialLayer::from_known(id, entity))
113 }
114
115 pub fn layers_with_offsets(self) -> impl Iterator<Item = MaterialLayerWithOffsets<'m>> + 'm {
117 self.model()
118 .of_type("IFCMATERIALLAYERWITHOFFSETS")
119 .map(|(id, entity)| MaterialLayerWithOffsets::from_known(id, entity))
120 }
121}