ifc_systems/authoring/error.rs
1//! Why a systems record was refused.
2
3use ifc_model::EntityId;
4use ifc_schema::SchemaVersion;
5
6/// Why a systems record was refused.
7#[derive(Debug, Clone, PartialEq, Eq)]
8#[non_exhaustive]
9pub enum SystemAuthoringError {
10 /// A value the schema constrains was not acceptable.
11 Invalid {
12 /// The entity being authored.
13 entity: &'static str,
14 /// The attribute at fault.
15 attribute: &'static str,
16 /// What was supplied.
17 value: String,
18 },
19 /// The model's header declares several schemas; release-bound
20 /// authoring binds to exactly one.
21 MultipleSchemas {
22 /// Number of `FILE_SCHEMA` declarations.
23 schemas: usize,
24 },
25 /// The model's header declares one schema with no bundled table, so no
26 /// layout can be trusted.
27 UnsupportedSchema {
28 /// The `FILE_SCHEMA` token as written.
29 schema: String,
30 },
31 /// The model's release does not declare this entity, such as
32 /// `IfcSpatialZone` in IFC2X3 or `IfcBuiltSystem` outside IFC4X3.
33 EntityNotInSchema {
34 /// The entity being authored.
35 entity: &'static str,
36 /// The release the model declares.
37 schema: SchemaVersion,
38 },
39 /// A value for an attribute the release does not declare, such as an
40 /// IFC2X3 `IfcZone.LongName`. It is refused rather than dropped.
41 AuthoringNotInSchema {
42 /// The entity being authored.
43 entity: &'static str,
44 /// The attribute, by its IFC4 name.
45 attribute: &'static str,
46 /// The release the model declares.
47 schema: SchemaVersion,
48 },
49 /// A value the release's declaration of the attribute cannot hold, such
50 /// as an `IfcDistributionSystemEnum` token IFC4 does not declare.
51 AuthoringValueType {
52 /// The entity being authored.
53 entity: &'static str,
54 /// The attribute, by its IFC4 name.
55 attribute: &'static str,
56 /// The type the release declares.
57 declared: &'static str,
58 /// The release the model declares.
59 schema: SchemaVersion,
60 },
61 /// The release requires an attribute the call leaves unset, such as the
62 /// IFC2X3 `IfcRoot.OwnerHistory` (#202). It is refused rather than
63 /// written as `$`.
64 AuthoringRequired {
65 /// The entity being authored.
66 entity: &'static str,
67 /// The attribute, by the release's own name.
68 attribute: &'static str,
69 /// The release the model declares.
70 schema: SchemaVersion,
71 },
72 /// A reference, such as a caller-supplied `OwnerHistory`, is neither in
73 /// the model nor staged on the transaction.
74 MissingReference {
75 /// The entity being authored.
76 entity: &'static str,
77 /// The reference attribute.
78 attribute: &'static str,
79 /// The missing entity.
80 target: EntityId,
81 },
82 /// A reference, such as a caller-supplied `OwnerHistory`, names an
83 /// entity of a type the release does not accept there.
84 WrongReferenceType {
85 /// The entity being authored.
86 entity: &'static str,
87 /// The reference attribute.
88 attribute: &'static str,
89 /// The referenced entity.
90 target: EntityId,
91 /// Its type.
92 actual: String,
93 /// The type the attribute requires.
94 expected: &'static str,
95 },
96}
97
98impl std::fmt::Display for SystemAuthoringError {
99 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
100 match self {
101 Self::Invalid {
102 entity,
103 attribute,
104 value,
105 } => write!(f, "{entity}.{attribute}: {value}"),
106 Self::MultipleSchemas { schemas } => write!(
107 f,
108 "the header declares {schemas} schemas; authoring binds to exactly one"
109 ),
110 Self::UnsupportedSchema { schema } => {
111 write!(
112 f,
113 "the header declares {schema}, which has no bundled table"
114 )
115 }
116 Self::EntityNotInSchema { entity, schema } => {
117 write!(f, "{entity} is not an entity of {schema:?}")
118 }
119 Self::AuthoringNotInSchema {
120 entity,
121 attribute,
122 schema,
123 } => write!(
124 f,
125 "cannot author {entity}.{attribute}: not declared by {schema:?}"
126 ),
127 Self::AuthoringValueType {
128 entity,
129 attribute,
130 declared,
131 schema,
132 } => write!(
133 f,
134 "cannot author {entity}.{attribute}: {schema:?} declares it {declared}"
135 ),
136 Self::AuthoringRequired {
137 entity,
138 attribute,
139 schema,
140 } => write!(f, "cannot author {entity}: {schema:?} requires {attribute}"),
141 Self::MissingReference {
142 entity,
143 attribute,
144 target,
145 } => write!(f, "{entity}.{attribute} references missing {target}"),
146 Self::WrongReferenceType {
147 entity,
148 attribute,
149 target,
150 actual,
151 expected,
152 } => write!(
153 f,
154 "{entity}.{attribute} references {target} of type {actual}; expected {expected}"
155 ),
156 }
157 }
158}
159
160impl std::error::Error for SystemAuthoringError {}
161
162/// Result of staging a systems record.
163pub type SystemAuthoringResult<T> = Result<T, SystemAuthoringError>;
164
165pub(super) fn invalid(
166 entity: &'static str,
167 attribute: &'static str,
168 value: impl Into<String>,
169) -> SystemAuthoringError {
170 SystemAuthoringError::Invalid {
171 entity,
172 attribute,
173 value: value.into(),
174 }
175}