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
//! Why a spatial record was refused.
use ifc_model::EntityId;
use ifc_schema::SchemaVersion;
/// Why a spatial record was refused.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum SpatialAuthoringError {
/// A value the schema constrains was not acceptable.
Invalid {
/// The entity being authored.
entity: &'static str,
/// The attribute at fault.
attribute: &'static str,
/// What was supplied.
value: String,
},
/// The model's header declares several schemas; release-bound
/// authoring binds to exactly one.
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 this entity, such as
/// `IfcRelDeclares` in IFC2X3 or `IfcRelPositions` outside IFC4X3.
EntityNotInSchema {
/// The entity being authored.
entity: &'static str,
/// The release the model declares.
schema: SchemaVersion,
},
/// A value for an attribute the release does not declare. It is
/// refused rather than dropped.
AuthoringNotInSchema {
/// The entity being authored.
entity: &'static str,
/// The attribute, by its IFC4 name.
attribute: &'static str,
/// The release the model declares.
schema: SchemaVersion,
},
/// A value the release's declaration of the attribute cannot hold,
/// such as an IFC4 enumeration token IFC2X3 does not declare.
AuthoringValueType {
/// The entity being authored.
entity: &'static str,
/// The attribute, by its IFC4 name.
attribute: &'static str,
/// The type the release declares.
declared: &'static str,
/// The release the model declares.
schema: SchemaVersion,
},
/// The release requires an attribute the call leaves unset, such as
/// the IFC2X3 `IfcRoot.OwnerHistory` (#202). It is refused rather than
/// written as `$`; the `*_with_owner_history` writers take the
/// `IfcOwnerHistory` IFC2X3 needs.
AuthoringRequired {
/// The entity being authored.
entity: &'static str,
/// The attribute, by the release's own name.
attribute: &'static str,
/// The release the model declares.
schema: SchemaVersion,
},
/// A reference names an entity neither in the model nor staged.
MissingReference {
/// The entity being authored.
entity: &'static str,
/// The reference attribute.
attribute: &'static str,
/// The missing entity.
target: EntityId,
},
/// A reference names an entity of a type the release does not accept
/// there, such as an `OwnerHistory` that is not an `IfcOwnerHistory`.
WrongReferenceType {
/// The entity being authored.
entity: &'static str,
/// The reference attribute.
attribute: &'static str,
/// The referenced entity.
target: EntityId,
/// Its type.
actual: String,
/// The type expected.
expected: &'static str,
},
}
impl std::fmt::Display for SpatialAuthoringError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::Invalid {
entity,
attribute,
value,
} => write!(f, "{entity}.{attribute}: {value}"),
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 entity of {schema:?}")
}
Self::AuthoringNotInSchema {
entity,
attribute,
schema,
} => write!(
f,
"cannot author {entity}.{attribute}: not declared by {schema:?}"
),
Self::AuthoringValueType {
entity,
attribute,
declared,
schema,
} => write!(
f,
"cannot author {entity}.{attribute}: {schema:?} declares it {declared}"
),
Self::AuthoringRequired {
entity,
attribute,
schema,
} => write!(f, "cannot author {entity}: {schema:?} requires {attribute}"),
Self::MissingReference {
entity,
attribute,
target,
} => write!(f, "{entity}.{attribute} references missing {target}"),
Self::WrongReferenceType {
entity,
attribute,
target,
actual,
expected,
} => write!(
f,
"{entity}.{attribute} references {target} of type {actual}; expected {expected}"
),
}
}
}
impl std::error::Error for SpatialAuthoringError {}
/// Result of staging a spatial record.
pub type SpatialAuthoringResult<T> = Result<T, SpatialAuthoringError>;
pub(crate) fn invalid(
entity: &'static str,
attribute: &'static str,
value: impl Into<String>,
) -> SpatialAuthoringError {
SpatialAuthoringError::Invalid {
entity,
attribute,
value: value.into(),
}
}