ifc_approval/error.rs
1//! Typed failures for bounded approval semantics.
2
3use ifc_model::EntityId;
4use ifc_schema::SchemaVersion;
5use thiserror::Error;
6
7/// Approval projection or authoring failure.
8#[derive(Debug, Clone, PartialEq, Error)]
9#[non_exhaustive]
10pub enum ApprovalError {
11 /// Entity kind differs from the requested projection.
12 #[error("expected {expected}, found {actual}")]
13 WrongEntityType {
14 /// Expected IFC entity.
15 expected: &'static str,
16 /// Actual IFC entity.
17 actual: String,
18 },
19 /// Required positional attribute is absent or null.
20 #[error("{entity} {id} is missing {attribute}")]
21 MissingAttribute {
22 /// Entity kind.
23 entity: &'static str,
24 /// Entity identifier.
25 id: EntityId,
26 /// Attribute name.
27 attribute: &'static str,
28 },
29 /// Attribute has the wrong value shape or cardinality.
30 #[error("{entity} {id}.{attribute} is invalid: {value}")]
31 InvalidValue {
32 /// Entity kind.
33 entity: &'static str,
34 /// Entity identifier.
35 id: EntityId,
36 /// Attribute name.
37 attribute: &'static str,
38 /// Diagnostic value.
39 value: String,
40 },
41 /// Requested entity is absent.
42 #[error("entity {id} does not exist")]
43 UnknownEntity {
44 /// Missing identifier.
45 id: EntityId,
46 },
47 /// Authored or projected reference does not resolve.
48 #[error("{entity} {id}.{attribute} reference {target} does not resolve")]
49 DanglingReference {
50 /// Relationship or record kind.
51 entity: &'static str,
52 /// Owning entity identifier.
53 id: EntityId,
54 /// Attribute name.
55 attribute: &'static str,
56 /// Missing target.
57 target: EntityId,
58 },
59 /// Resolved reference is outside the declared IFC SELECT/type.
60 #[error("{entity} {id}.{attribute} target {target} has {actual}, expected {expected}")]
61 ReferenceType {
62 /// Relationship or record kind.
63 entity: &'static str,
64 /// Owning entity identifier.
65 id: EntityId,
66 /// Attribute name.
67 attribute: &'static str,
68 /// Referenced target.
69 target: EntityId,
70 /// Expected entity or SELECT.
71 expected: &'static str,
72 /// Actual entity kind.
73 actual: String,
74 },
75 /// Declared WHERE-style rule failed.
76 #[error("{entity} {id} violates {rule}: {detail}")]
77 Semantic {
78 /// Entity kind.
79 entity: &'static str,
80 /// Entity identifier.
81 id: EntityId,
82 /// Bounded rule name.
83 rule: &'static str,
84 /// Human-readable detail.
85 detail: String,
86 },
87 /// Draft value is invalid before staging.
88 #[error("cannot author {entity}.{attribute}: {value}")]
89 AuthoringInvalid {
90 /// Entity kind.
91 entity: &'static str,
92 /// Attribute or rule.
93 attribute: &'static str,
94 /// Rejected value.
95 value: String,
96 },
97 /// Draft reference is outside the required entity/SELECT.
98 #[error("authoring target {target} has {actual}, expected {expected}")]
99 AuthoringReferenceType {
100 /// Referenced target.
101 target: EntityId,
102 /// Expected entity or SELECT.
103 expected: &'static str,
104 /// Actual entity kind.
105 actual: String,
106 },
107 /// The model's header declares several schemas; authoring binds to
108 /// exactly one release.
109 #[error("the header declares {schemas} schemas; authoring binds to exactly one")]
110 MultipleSchemas {
111 /// Number of `FILE_SCHEMA` declarations.
112 schemas: usize,
113 },
114 /// The model's header declares one schema this crate is not verified
115 /// against (anything but IFC2X3, IFC4 and IFC4X3), so no layout can be
116 /// trusted. Never read or written as another release.
117 #[error("the header declares {schema}, which this crate is not verified against")]
118 UnsupportedSchema {
119 /// The `FILE_SCHEMA` token as written.
120 schema: String,
121 },
122 /// An accessor asked for an attribute the model's release does not
123 /// declare, such as `RequestingApproval` on an IFC2X3 `IfcApproval`.
124 /// Never read from the slot another release gives it (#212).
125 #[error("{entity} {id}.{attribute} is not defined by {schema:?}")]
126 NotInSchema {
127 /// Entity kind.
128 entity: &'static str,
129 /// Entity identifier.
130 id: EntityId,
131 /// The attribute, by this crate's (IFC4) name.
132 attribute: &'static str,
133 /// The release the model is read against.
134 schema: SchemaVersion,
135 },
136 /// A text accessor met an attribute the release types as an entity
137 /// record, such as the IFC2X3 `IfcApproval.ApprovalDateTime`, an
138 /// `IfcDateTimeSelect`. The value is valid; read it through `target`.
139 #[error("{entity} {id}.{attribute} is the record {target}, not text")]
140 StructuredValue {
141 /// Entity kind.
142 entity: &'static str,
143 /// Entity identifier.
144 id: EntityId,
145 /// The attribute, by this crate's (IFC4) name.
146 attribute: &'static str,
147 /// The entity record holding the value.
148 target: EntityId,
149 },
150 /// The model's release does not declare this entity, such as
151 /// `IfcResourceApprovalRelationship` in IFC2X3.
152 #[error("{entity} is not an instantiable entity of {schema:?}")]
153 EntityNotInSchema {
154 /// The entity type.
155 entity: &'static str,
156 /// The release the model declares.
157 schema: SchemaVersion,
158 },
159 /// A draft supplied a value for an attribute the model's release does
160 /// not declare, such as a `Status` for an IFC2X3 `IfcApproval`. It is
161 /// refused rather than dropped.
162 #[error("cannot author {entity}.{attribute}: not defined by {schema:?}")]
163 AuthoringNotInSchema {
164 /// The entity type being authored.
165 entity: &'static str,
166 /// The attribute, by this crate's (IFC4) name.
167 attribute: &'static str,
168 /// The release the model declares.
169 schema: SchemaVersion,
170 },
171 /// A draft supplied a value in a form the release's declaration cannot
172 /// hold, such as text where IFC2X3 declares an `IfcDateTimeSelect`
173 /// record, or several related approvals where IFC2X3 declares one.
174 #[error("cannot author {entity}.{attribute}: {schema:?} declares {declared}")]
175 AuthoringValueType {
176 /// The entity type being authored.
177 entity: &'static str,
178 /// The attribute, by this crate's (IFC4) name.
179 attribute: &'static str,
180 /// The type the release declares.
181 declared: &'static str,
182 /// The release the model declares.
183 schema: SchemaVersion,
184 },
185 /// The model's release requires an attribute the authoring call leaves
186 /// unset, such as the IFC2X3 `IfcRoot.OwnerHistory`.
187 #[error("cannot author {entity}: {schema:?} requires {attribute}")]
188 AuthoringRequired {
189 /// The entity type being authored.
190 entity: &'static str,
191 /// The required attribute, as the release names it.
192 attribute: &'static str,
193 /// The release the model declares.
194 schema: SchemaVersion,
195 },
196}
197
198/// Result alias for approval operations.
199pub type ApprovalResult<T> = Result<T, ApprovalError>;