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 systems record was refused.
use ifc_model::EntityId;
use ifc_schema::SchemaVersion;
/// Why a systems record was refused.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum SystemAuthoringError {
/// 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
/// `IfcSpatialZone` in IFC2X3 or `IfcBuiltSystem` 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, such as an
/// IFC2X3 `IfcZone.LongName`. 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 `IfcDistributionSystemEnum` token IFC4 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 `$`.
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, such as a caller-supplied `OwnerHistory`, is neither in
/// the model nor staged on the transaction.
MissingReference {
/// The entity being authored.
entity: &'static str,
/// The reference attribute.
attribute: &'static str,
/// The missing entity.
target: EntityId,
},
/// A reference, such as a caller-supplied `OwnerHistory`, names an
/// entity of a type the release does not accept there.
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 the attribute requires.
expected: &'static str,
},
}
impl std::fmt::Display for SystemAuthoringError {
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 SystemAuthoringError {}
/// Result of staging a systems record.
pub type SystemAuthoringResult<T> = Result<T, SystemAuthoringError>;
pub(super) fn invalid(
entity: &'static str,
attribute: &'static str,
value: impl Into<String>,
) -> SystemAuthoringError {
SystemAuthoringError::Invalid {
entity,
attribute,
value: value.into(),
}
}