1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
//! Typed failures while interpreting or authoring IFC external references.
use ifc_model::EntityId;
use ifc_schema::SchemaVersion;
use thiserror::Error;
/// Failure decoding, cross-checking, or authoring classification/document/library records.
#[derive(Debug, Clone, PartialEq, Error)]
#[non_exhaustive]
pub enum ClassificationError {
/// Entity did not have the expected IFC type.
#[error("expected {expected}, found {actual}")]
WrongEntityType {
/// IFC type name expected at this position.
expected: &'static str,
/// IFC type name actually found.
actual: String,
},
/// A required attribute was unset (`$` or `*`) or absent.
#[error("{entity} {id} is missing required attribute {attribute}")]
MissingAttribute {
/// IFC entity type of the offending instance.
entity: &'static str,
/// Id of the offending instance.
id: EntityId,
/// Name of the missing attribute.
attribute: &'static str,
},
/// An attribute was present but failed to decode as its expected shape.
#[error("{entity} {id} has invalid {attribute}: {value}")]
InvalidValue {
/// IFC entity type of the offending instance.
entity: &'static str,
/// Id of the offending instance.
id: EntityId,
/// Name of the invalid attribute.
attribute: &'static str,
/// Debug rendering of the offending value.
value: String,
},
/// A referenced entity id does not exist in the model.
#[error("entity {id} does not exist")]
UnknownEntity {
/// Id that could not be resolved.
id: EntityId,
},
/// An attribute reference points at an id that is not present in the model.
#[error("{entity} {id}.{attribute} reference {target} does not resolve")]
DanglingReference {
/// IFC entity type holding the dangling reference.
entity: &'static str,
/// Id of the entity holding the dangling reference.
id: EntityId,
/// Name of the attribute holding the dangling reference.
attribute: &'static str,
/// Id that could not be resolved.
target: EntityId,
},
/// An attribute reference resolves but the target entity has the wrong type for its select.
#[error("{entity} {id}.{attribute} reference {target} has type {actual}, expected {expected}")]
ReferenceType {
/// IFC entity type holding the mistyped reference.
entity: &'static str,
/// Id of the entity holding the mistyped reference.
id: EntityId,
/// Name of the attribute holding the mistyped reference.
attribute: &'static str,
/// Id of the mistyped target.
target: EntityId,
/// Select or type name the target was expected to satisfy.
expected: &'static str,
/// IFC type name the target actually has.
actual: String,
},
/// Following `ReferencedSource` links revisited an already-seen entity.
#[error("classification hierarchy contains a cycle: {path:?}")]
Cycle {
/// Entity ids on the cycle, in traversal order.
path: Vec<EntityId>,
},
/// Hierarchy traversal exceeded the caller-supplied node or depth budget.
#[error("classification hierarchy exceeded max_depth={max_depth} or max_nodes={max_nodes}")]
BudgetExceeded {
/// Maximum edge depth allowed.
max_depth: usize,
/// Maximum number of nodes allowed.
max_nodes: usize,
},
/// An occurrence object is related to more than one `IfcRelDefinesByType` type.
#[error("object {object} has {count} assigned IFC types")]
AmbiguousType {
/// The occurrence object with the ambiguous type assignment.
object: EntityId,
/// Number of types the object was found related to.
count: usize,
},
/// A draft value failed schema validation before staging.
#[error("cannot author {entity}.{attribute}: {value}")]
AuthoringInvalid {
/// IFC entity type being authored.
entity: &'static str,
/// Name of the offending attribute.
attribute: &'static str,
/// Description of why the value is invalid.
value: String,
},
/// A draft reference resolves to a staged or committed entity of the wrong type.
#[error("authoring reference {target} has type {actual}, expected {expected}")]
AuthoringReferenceType {
/// Id of the mistyped reference target.
target: EntityId,
/// Select or type name the target was expected to satisfy.
expected: &'static str,
/// IFC type name the target actually has.
actual: String,
},
/// The header declares several schemas, so no single release can be
/// bound to read or write the model against.
#[error("the header declares {schemas} schemas; classification reads bind to exactly one")]
MultipleSchemas {
/// Number of `FILE_SCHEMA` declarations.
schemas: usize,
},
/// The release the model is read against does not define this attribute
/// or record, for example `Description` on an IFC2X3 `IfcClassification`
/// or any `IfcExternalReferenceRelationship` in an IFC2X3 model. This is
/// never reported as an unset (`None`) value.
#[error("{entity} {id}.{attribute} is not defined by {schema:?}")]
NotInSchema {
/// IFC entity type of the instance.
entity: &'static str,
/// Id of the instance.
id: EntityId,
/// Attribute name, as this crate's accessor names it.
attribute: &'static str,
/// The release the model is read against.
schema: SchemaVersion,
},
/// A text accessor met an attribute the bound release types as an entity
/// record, such as an IFC2X3 `IfcCalendarDate` edition date. The value is
/// valid; read it structurally through `target`.
#[error("{entity} {id}.{attribute} is the record {target}, not text")]
StructuredValue {
/// IFC entity type of the instance.
entity: &'static str,
/// Id of the instance.
id: EntityId,
/// Attribute name.
attribute: &'static str,
/// The entity record holding the value.
target: EntityId,
},
/// The header declares one schema this crate has no bundled table for,
/// so no slot position can be trusted. Never read as IFC4.
#[error("the header declares {schema}, which has no bundled schema table")]
UnsupportedSchema {
/// The `FILE_SCHEMA` token as written.
schema: String,
},
/// An authoring call would write a record type the model's release
/// cannot instantiate, such as an `IfcExternalReferenceRelationship`
/// into an IFC2X3 model.
#[error("cannot author {entity}: not an instantiable entity of {schema:?}")]
EntityNotInSchema {
/// The IFC entity type name.
entity: &'static str,
/// The release the model is bound to.
schema: SchemaVersion,
},
/// An authoring call supplied a value for an attribute the model's
/// release does not declare, such as a `Description` for an IFC2X3
/// `IfcClassification`. The value is refused, never silently dropped.
#[error("cannot author {entity}.{attribute}: not defined by {schema:?}")]
AuthoringNotInSchema {
/// The IFC entity type name being authored.
entity: &'static str,
/// The attribute, as this crate names it (IFC4).
attribute: &'static str,
/// The release the model is bound to.
schema: SchemaVersion,
},
/// The model's release requires an attribute the authoring call leaves
/// unset, such as the IFC2X3 `IfcRoot.OwnerHistory` or the IFC2X3
/// `IfcClassification.Source`.
#[error("cannot author {entity}: {schema:?} requires {attribute}")]
AuthoringRequired {
/// The IFC entity type name being authored.
entity: &'static str,
/// The required attribute, as the release names it.
attribute: &'static str,
/// The release the model is bound to.
schema: SchemaVersion,
},
/// An authoring call supplied text for an attribute the model's release
/// types as an entity record, such as an IFC2X3 `IfcCalendarDate`
/// `EditionDate`. The text is refused rather than written into a slot
/// that cannot hold it.
#[error("cannot author {entity}.{attribute} as text: {schema:?} declares {declared}")]
AuthoringValueType {
/// The IFC entity type name being authored.
entity: &'static str,
/// The attribute, as this crate names it (IFC4).
attribute: &'static str,
/// The type the release declares for the attribute.
declared: &'static str,
/// The release the model is bound to.
schema: SchemaVersion,
},
}
/// Result of a classification/document/library query or authoring operation.
pub type ClassificationResult<T> = Result<T, ClassificationError>;