ifc_material/error.rs
1//! Typed failures while interpreting IFC material-resource entities.
2
3use ifc_model::EntityId;
4use ifc_schema::SchemaVersion;
5use thiserror::Error;
6
7/// A malformed, ambiguous, or unresolved material projection.
8#[derive(Debug, Clone, PartialEq, Error)]
9#[non_exhaustive]
10pub enum MaterialError {
11 /// A projection expected one entity type but the model holds another.
12 #[error("expected {expected}, found {actual}")]
13 WrongEntityType {
14 /// The IFC entity type name that was expected.
15 expected: &'static str,
16 /// The IFC entity type name actually found on the record.
17 actual: String,
18 },
19 /// A required attribute slot on the entity is absent (unset `$`).
20 #[error("{entity} {id} is missing required attribute {attribute}")]
21 MissingAttribute {
22 /// The IFC entity type name.
23 entity: &'static str,
24 /// The id of the entity missing the attribute.
25 id: EntityId,
26 /// The name of the missing attribute.
27 attribute: &'static str,
28 },
29 /// An attribute is present but its value violates a WHERE rule or type
30 /// constraint.
31 #[error("{entity} {id} has invalid {attribute}: {value}")]
32 InvalidValue {
33 /// The IFC entity type name.
34 entity: &'static str,
35 /// The id of the entity with the invalid attribute.
36 id: EntityId,
37 /// The name of the invalid attribute.
38 attribute: &'static str,
39 /// A rendering of the offending value.
40 value: String,
41 },
42 /// A value supplied to an authoring function cannot be written to the
43 /// named entity attribute.
44 #[error("cannot author {entity}.{attribute}: {value}")]
45 AuthoringInvalid {
46 /// The IFC entity type name being authored.
47 entity: &'static str,
48 /// The name of the attribute that rejected the value.
49 attribute: &'static str,
50 /// A rendering of the rejected value.
51 value: String,
52 },
53 /// An authoring-time reference points at an entity of the wrong type.
54 #[error("authoring reference {target} has type {actual}, expected {expected}")]
55 AuthoringReferenceType {
56 /// The id of the referenced entity.
57 target: EntityId,
58 /// The IFC entity type name that was expected.
59 expected: &'static str,
60 /// The IFC entity type name actually found at `target`.
61 actual: String,
62 },
63 /// A referenced entity id does not exist in the model.
64 #[error("entity {id} does not exist")]
65 UnknownEntity {
66 /// The id that could not be resolved.
67 id: EntityId,
68 },
69 /// A reference field points at an id absent from the model.
70 #[error("reference {target} from {source_id} does not resolve")]
71 DanglingReference {
72 /// The id of the entity holding the reference.
73 source_id: EntityId,
74 /// The unresolved target id.
75 target: EntityId,
76 },
77 /// A reference resolves to an entity, but of the wrong type.
78 #[error("reference {target} from {source_id} has type {actual}, expected {expected}")]
79 ReferenceType {
80 /// The id of the entity holding the reference.
81 source_id: EntityId,
82 /// The id of the referenced entity.
83 target: EntityId,
84 /// The IFC entity type name that was expected.
85 expected: &'static str,
86 /// The IFC entity type name actually found at `target`.
87 actual: String,
88 },
89 /// The object is directly related to more than one `IfcMaterial`
90 /// via `IfcRelAssociatesMaterial`, so the single active material cannot
91 /// be determined.
92 #[error("object {object} has {count} direct material assignments")]
93 AmbiguousAssignment {
94 /// The id of the object with conflicting assignments.
95 object: EntityId,
96 /// The number of direct material assignments found.
97 count: usize,
98 },
99 /// The object is typed by more than one `IfcTypeObject`, so its
100 /// inherited material cannot be determined unambiguously.
101 #[error("object {object} has {count} assigned IFC types")]
102 AmbiguousType {
103 /// The id of the object with conflicting type relationships.
104 object: EntityId,
105 /// The number of `IfcTypeObject` relationships found.
106 count: usize,
107 },
108 /// The header declares several schemas, so no single release can be
109 /// bound to read or write the model against.
110 #[error("the header declares {schemas} schemas; material reads bind to exactly one")]
111 MultipleSchemas {
112 /// Number of `FILE_SCHEMA` declarations.
113 schemas: usize,
114 },
115 /// The header declares one schema this crate has no bundled table for,
116 /// so no slot position can be trusted.
117 #[error("the header declares {schema}, which has no bundled schema table")]
118 UnsupportedSchema {
119 /// The `FILE_SCHEMA` token as written.
120 schema: String,
121 },
122 /// The release the model is read against does not declare this
123 /// attribute, for example `Category` on an IFC2X3 `IfcMaterial` or
124 /// `Name` on an IFC2X3 `IfcMaterialLayer`. This is never reported as an
125 /// unset (`None`) value, and no other slot is read in its place.
126 #[error("{entity} {id}.{attribute} is not defined by {schema:?}")]
127 NotInSchema {
128 /// IFC entity type of the instance.
129 entity: &'static str,
130 /// Id of the instance.
131 id: EntityId,
132 /// Attribute name, as this crate's accessor names it (IFC4).
133 attribute: &'static str,
134 /// The release the model is read against.
135 schema: SchemaVersion,
136 },
137 /// The release the model is bound to has no instantiable entity of this
138 /// type, for example an `IfcMaterialConstituentSet` or
139 /// `IfcMaterialProfileSet` in an IFC2X3 model, or the abstract IFC2X3
140 /// `IfcMaterialProperties`. Such a record is refused, not decoded with
141 /// another release's layout.
142 #[error("{entity} is not an instantiable entity of {schema:?}")]
143 EntityNotInSchema {
144 /// The IFC entity type name.
145 entity: &'static str,
146 /// The record, when one is being read; `None` when authoring.
147 id: Option<EntityId>,
148 /// The release the model is bound to.
149 schema: SchemaVersion,
150 },
151 /// An authoring call supplied a value for an attribute the model's
152 /// release does not declare, such as a layer `Name` for an IFC2X3
153 /// model. The value is refused rather than silently dropped.
154 #[error("cannot author {entity}.{attribute}: not defined by {schema:?}")]
155 AuthoringNotInSchema {
156 /// The IFC entity type name being authored.
157 entity: &'static str,
158 /// The attribute, as this crate names it (IFC4).
159 attribute: &'static str,
160 /// The release the model is bound to.
161 schema: SchemaVersion,
162 },
163 /// The model's release requires an attribute the authoring call leaves
164 /// unset, such as the IFC2X3 `IfcRoot.OwnerHistory`.
165 #[error("cannot author {entity}: {schema:?} requires {attribute}")]
166 AuthoringRequired {
167 /// The IFC entity type name being authored.
168 entity: &'static str,
169 /// The required attribute, as the release names it.
170 attribute: &'static str,
171 /// The release the model is bound to.
172 schema: SchemaVersion,
173 },
174}
175
176/// Convenience alias for results of material-projection operations.
177pub type MaterialResult<T> = Result<T, MaterialError>;