Skip to main content

ifc_classification/
error.rs

1//! Typed failures while interpreting or authoring IFC external references.
2
3use ifc_model::EntityId;
4use thiserror::Error;
5
6/// Failure decoding, cross-checking, or authoring classification/document/library records.
7#[derive(Debug, Clone, PartialEq, Error)]
8#[non_exhaustive]
9pub enum ClassificationError {
10    /// Entity did not have the expected IFC type.
11    #[error("expected {expected}, found {actual}")]
12    WrongEntityType {
13        /// IFC type name expected at this position.
14        expected: &'static str,
15        /// IFC type name actually found.
16        actual: String,
17    },
18    /// A required attribute was unset (`$` or `*`) or absent.
19    #[error("{entity} {id} is missing required attribute {attribute}")]
20    MissingAttribute {
21        /// IFC entity type of the offending instance.
22        entity: &'static str,
23        /// Id of the offending instance.
24        id: EntityId,
25        /// Name of the missing attribute.
26        attribute: &'static str,
27    },
28    /// An attribute was present but failed to decode as its expected shape.
29    #[error("{entity} {id} has invalid {attribute}: {value}")]
30    InvalidValue {
31        /// IFC entity type of the offending instance.
32        entity: &'static str,
33        /// Id of the offending instance.
34        id: EntityId,
35        /// Name of the invalid attribute.
36        attribute: &'static str,
37        /// Debug rendering of the offending value.
38        value: String,
39    },
40    /// A referenced entity id does not exist in the model.
41    #[error("entity {id} does not exist")]
42    UnknownEntity {
43        /// Id that could not be resolved.
44        id: EntityId,
45    },
46    /// An attribute reference points at an id that is not present in the model.
47    #[error("{entity} {id}.{attribute} reference {target} does not resolve")]
48    DanglingReference {
49        /// IFC entity type holding the dangling reference.
50        entity: &'static str,
51        /// Id of the entity holding the dangling reference.
52        id: EntityId,
53        /// Name of the attribute holding the dangling reference.
54        attribute: &'static str,
55        /// Id that could not be resolved.
56        target: EntityId,
57    },
58    /// An attribute reference resolves but the target entity has the wrong type for its select.
59    #[error("{entity} {id}.{attribute} reference {target} has type {actual}, expected {expected}")]
60    ReferenceType {
61        /// IFC entity type holding the mistyped reference.
62        entity: &'static str,
63        /// Id of the entity holding the mistyped reference.
64        id: EntityId,
65        /// Name of the attribute holding the mistyped reference.
66        attribute: &'static str,
67        /// Id of the mistyped target.
68        target: EntityId,
69        /// Select or type name the target was expected to satisfy.
70        expected: &'static str,
71        /// IFC type name the target actually has.
72        actual: String,
73    },
74    /// Following `ReferencedSource` links revisited an already-seen entity.
75    #[error("classification hierarchy contains a cycle: {path:?}")]
76    Cycle {
77        /// Entity ids on the cycle, in traversal order.
78        path: Vec<EntityId>,
79    },
80    /// Hierarchy traversal exceeded the caller-supplied node or depth budget.
81    #[error("classification hierarchy exceeded max_depth={max_depth} or max_nodes={max_nodes}")]
82    BudgetExceeded {
83        /// Maximum edge depth allowed.
84        max_depth: usize,
85        /// Maximum number of nodes allowed.
86        max_nodes: usize,
87    },
88    /// An occurrence object is related to more than one `IfcRelDefinesByType` type.
89    #[error("object {object} has {count} assigned IFC types")]
90    AmbiguousType {
91        /// The occurrence object with the ambiguous type assignment.
92        object: EntityId,
93        /// Number of types the object was found related to.
94        count: usize,
95    },
96    /// A draft value failed schema validation before staging.
97    #[error("cannot author {entity}.{attribute}: {value}")]
98    AuthoringInvalid {
99        /// IFC entity type being authored.
100        entity: &'static str,
101        /// Name of the offending attribute.
102        attribute: &'static str,
103        /// Description of why the value is invalid.
104        value: String,
105    },
106    /// A draft reference resolves to a staged or committed entity of the wrong type.
107    #[error("authoring reference {target} has type {actual}, expected {expected}")]
108    AuthoringReferenceType {
109        /// Id of the mistyped reference target.
110        target: EntityId,
111        /// Select or type name the target was expected to satisfy.
112        expected: &'static str,
113        /// IFC type name the target actually has.
114        actual: String,
115    },
116}
117
118/// Result of a classification/document/library query or authoring operation.
119pub type ClassificationResult<T> = Result<T, ClassificationError>;