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
//! Why an occurrence was refused.
use ifc_model::EntityId;
use ifc_schema::SchemaVersion;
/// Why an occurrence was refused.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum OccurrenceError {
/// `GlobalId` did not parse as a 22-character IFC GUID.
MalformedGuid {
/// The offending value.
value: String,
},
/// The token is not a member of this class's own enum.
UnknownPredefinedType {
/// STEP class.
entity: &'static str,
/// The offending token.
token: String,
},
/// The class has no `PredefinedType` attribute at all.
NoPredefinedType {
/// STEP class.
entity: &'static str,
},
/// `USERDEFINED` was given without an `ObjectType` naming it.
UserDefinedWithoutObjectType {
/// STEP class.
entity: &'static str,
},
/// The occurrence was typed by a class the bound release does not pair
/// with it.
WrongTypeClass {
/// STEP class of the occurrence.
entity: &'static str,
/// The only class the release permits, such as `IFCDOORTYPE` for an
/// IFC4 `IfcDoor` or `IFCDOORSTYLE` for an IFC2X3 one.
expected: &'static str,
/// What the referenced entity actually is.
found: String,
},
/// The class permits no type at all, but one was supplied.
TypingNotPermitted {
/// STEP class.
entity: &'static str,
},
/// The bound release pairs no type class with this occurrence class,
/// such as an IFC2X3 `IfcStair`, whose `IfcStairType` IFC2X3 does not
/// declare, but one was supplied (#214).
TypeClassNotInSchema {
/// STEP class.
entity: &'static str,
/// The release the model declares.
schema: SchemaVersion,
},
/// The typed-by reference does not resolve in the model.
UnresolvedType {
/// The dangling id.
id: EntityId,
},
/// An enumeration token outside the enumeration the bound release
/// declares for the attribute, such as a `ShapeType` or `BarRole`.
UnknownToken {
/// STEP class.
entity: &'static str,
/// The attribute.
attribute: &'static str,
/// The offending token.
token: String,
},
/// A measure the attribute's type does not admit: a non-positive or
/// non-finite `IfcPositiveLengthMeasure`, or a non-finite
/// `IfcAreaMeasure`.
InvalidMeasure {
/// STEP class.
entity: &'static str,
/// The attribute.
attribute: &'static str,
/// The offending value, as written by `{:?}`.
value: String,
},
/// The model's header declares several schemas; authoring binds to
/// exactly one release.
MultipleSchemas {
/// Number of `FILE_SCHEMA` declarations.
schemas: usize,
},
/// The model's header declares one schema with no bundled table, so no
/// layout can be trusted.
UnsupportedSchema {
/// The `FILE_SCHEMA` token as written.
schema: String,
},
/// The model's release does not declare the class, or declares it
/// abstract, such as `IfcBorehole` (IFC4X3 only) in an IFC4 model.
EntityNotInSchema {
/// STEP class.
entity: &'static str,
/// The release the model declares.
schema: SchemaVersion,
},
/// A value for an attribute the model's release does not declare on the
/// class. It is refused rather than dropped.
AuthoringNotInSchema {
/// STEP class.
entity: &'static str,
/// The attribute.
attribute: &'static str,
/// The release the model declares.
schema: SchemaVersion,
},
/// The model's release requires an attribute the call leaves unset,
/// such as the IFC2X3 `IfcRoot.OwnerHistory`.
AuthoringRequired {
/// STEP class.
entity: &'static str,
/// The required attribute, as the release names it.
attribute: &'static str,
/// The release the model declares.
schema: SchemaVersion,
},
/// The owner-history reference resolves neither in the model nor on the
/// transaction.
UnresolvedOwnerHistory {
/// The dangling id.
id: EntityId,
},
/// The owner-history reference is not an `IfcOwnerHistory`.
NotAnOwnerHistory {
/// The referenced id.
id: EntityId,
/// What the referenced entity actually is.
found: String,
},
}
impl std::fmt::Display for OccurrenceError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::MalformedGuid { value } => write!(f, "malformed GlobalId {value:?}"),
Self::UnknownPredefinedType { entity, token } => {
write!(f, "{entity}.PredefinedType: {token} is not a member")
}
Self::NoPredefinedType { entity } => write!(f, "{entity} has no PredefinedType"),
Self::UserDefinedWithoutObjectType { entity } => {
write!(f, "{entity}: USERDEFINED needs an ObjectType")
}
Self::WrongTypeClass {
entity,
expected,
found,
} => write!(f, "{entity} is typed by {expected}, not {found}"),
Self::TypingNotPermitted { entity } => write!(f, "{entity} takes no type"),
Self::TypeClassNotInSchema { entity, schema } => {
write!(f, "{schema:?} pairs no type class with {entity}")
}
Self::UnresolvedType { id } => write!(f, "type #{} does not exist", id.0),
Self::UnknownToken {
entity,
attribute,
token,
} => write!(f, "{entity}.{attribute}: {token} is not a member"),
Self::InvalidMeasure {
entity,
attribute,
value,
} => write!(f, "{entity}.{attribute}: {value} is not admitted"),
Self::MultipleSchemas { schemas } => write!(
f,
"the header declares {schemas} schemas; authoring binds to exactly one"
),
Self::UnsupportedSchema { schema } => {
write!(
f,
"the header declares {schema}, which has no bundled table"
)
}
Self::EntityNotInSchema { entity, schema } => {
write!(f, "{entity} is not an instantiable entity of {schema:?}")
}
Self::AuthoringNotInSchema {
entity,
attribute,
schema,
} => write!(
f,
"cannot author {entity}.{attribute}: not defined by {schema:?}"
),
Self::AuthoringRequired {
entity,
attribute,
schema,
} => write!(f, "cannot author {entity}: {schema:?} requires {attribute}"),
Self::UnresolvedOwnerHistory { id } => {
write!(f, "owner history #{} does not exist", id.0)
}
Self::NotAnOwnerHistory { id, found } => {
write!(f, "#{} is a {found}, not an IfcOwnerHistory", id.0)
}
}
}
}
impl std::error::Error for OccurrenceError {}
/// Result alias for this crate.
pub type OccurrenceResult<T> = Result<T, OccurrenceError>;