Skip to main content

ifc_control/
error.rs

1//! Typed failures for bounded IFC control semantics.
2
3use ifc_model::EntityId;
4use thiserror::Error;
5
6/// Control projection or authoring failure.
7///
8/// Only the variants this crate can actually raise are declared. A
9/// variant that no code path constructs is a promise the crate does
10/// not keep, and callers write dead match arms for it.
11#[derive(Debug, Clone, PartialEq, Error)]
12#[non_exhaustive]
13pub enum ControlError {
14    /// Entity kind differs from the requested projection.
15    #[error("expected {expected}, found {actual}")]
16    WrongEntityType {
17        /// Expected IFC entity.
18        expected: &'static str,
19        /// Actual IFC entity.
20        actual: String,
21    },
22    /// Required positional attribute is absent or null.
23    #[error("{entity} {id} is missing {attribute}")]
24    MissingAttribute {
25        /// Entity kind.
26        entity: &'static str,
27        /// Entity identifier.
28        id: EntityId,
29        /// Attribute name.
30        attribute: &'static str,
31    },
32    /// Requested entity is absent.
33    #[error("entity {id} does not exist")]
34    UnknownEntity {
35        /// Missing identifier.
36        id: EntityId,
37    },
38    /// Draft value is invalid before staging, including an `OwnerHistory`
39    /// that is not an `IfcOwnerHistory`.
40    #[error("cannot author {entity}.{attribute}: {value}")]
41    AuthoringInvalid {
42        /// Entity kind.
43        entity: &'static str,
44        /// Attribute or rule.
45        attribute: &'static str,
46        /// Rejected value.
47        value: String,
48    },
49    /// The relating control of an assignment, or the record a reader was
50    /// asked for, is not one this crate owns.
51    ///
52    /// Cost schedules, cost items and work controls are `IfcControl`s
53    /// too; their own crates write and read them.
54    #[error("{id} is {actual}, not a control ifc-control owns")]
55    ForeignControl {
56        /// The offered relating control.
57        id: EntityId,
58        /// Its type name.
59        actual: String,
60    },
61    /// The schema in use does not declare this entity.
62    ///
63    /// Authoring an entity the schema omits is a caller error, not a
64    /// silently-skipped attribute.
65    #[error("{schema} does not declare {entity}")]
66    UnsupportedEntity {
67        /// Schema name.
68        schema: String,
69        /// Entity that is not declared.
70        entity: &'static str,
71    },
72    /// The model's header declares several schemas; release-bound
73    /// authoring binds to exactly one.
74    #[error("the header declares {schemas} schemas; authoring binds to exactly one")]
75    MultipleSchemas {
76        /// Number of `FILE_SCHEMA` declarations.
77        schemas: usize,
78    },
79    /// The model's header declares one schema with no bundled table, so no
80    /// layout can be trusted.
81    #[error("the header declares {schema}, which has no bundled table")]
82    UnsupportedSchema {
83        /// The `FILE_SCHEMA` token as written.
84        schema: String,
85    },
86    /// A draft supplied a value for an attribute the release does not
87    /// declare, such as a `PredefinedType` for an IFC2X3 `IfcPermit`. It is
88    /// refused rather than dropped.
89    #[error("cannot author {entity}.{attribute}: not declared by {schema}")]
90    AuthoringNotInSchema {
91        /// Entity kind.
92        entity: &'static str,
93        /// The attribute, by its IFC4 name.
94        attribute: &'static str,
95        /// Schema name.
96        schema: String,
97    },
98    /// A draft supplied a value the release's declaration of the attribute
99    /// cannot hold.
100    #[error("cannot author {entity}.{attribute}: {schema} declares it {declared}")]
101    AuthoringValueType {
102        /// Entity kind.
103        entity: &'static str,
104        /// The attribute, by its IFC4 name.
105        attribute: &'static str,
106        /// The type the release declares.
107        declared: String,
108        /// Schema name.
109        schema: String,
110    },
111    /// The release requires an attribute the call leaves unset, such as the
112    /// IFC2X3 `IfcRoot.OwnerHistory` (#198, #202) or `IfcPermit.PermitID`.
113    /// It is refused rather than written as `$`; the `*_with_owner_history`
114    /// writers take the `IfcOwnerHistory` IFC2X3 needs.
115    #[error("cannot author {entity}: {schema} requires {attribute}")]
116    AuthoringRequired {
117        /// Entity kind.
118        entity: &'static str,
119        /// The attribute, by the release's own name.
120        attribute: String,
121        /// Schema name.
122        schema: String,
123    },
124    /// A stored record holds, in a slot its release declares, a value that
125    /// declaration cannot hold (text where an enumeration belongs, a token
126    /// outside the release's enumeration). It is refused rather than read
127    /// as absent.
128    #[error("{entity} {id}: {schema} declares {attribute} as {declared}; the record holds another value")]
129    InvalidAttribute {
130        /// Entity kind.
131        entity: &'static str,
132        /// Entity identifier.
133        id: EntityId,
134        /// The attribute, by the release's own name.
135        attribute: &'static str,
136        /// The type the release declares.
137        declared: String,
138        /// Schema name.
139        schema: String,
140    },
141    /// A stored record has more attributes than its release declares, so
142    /// its layout is not the release's and no slot can be trusted.
143    #[error("{entity} {id} has {found} attributes; {schema} declares {declared}")]
144    ExtraAttributes {
145        /// Entity kind.
146        entity: &'static str,
147        /// Entity identifier.
148        id: EntityId,
149        /// Attributes the release declares.
150        declared: usize,
151        /// Attributes the record holds.
152        found: usize,
153        /// Schema name.
154        schema: String,
155    },
156}
157
158/// Result alias for control operations.
159pub type ControlResult<T> = Result<T, ControlError>;