Skip to main content

ifc_constraint/
error.rs

1//! Typed failures for bounded IFC4 constraint semantics.
2
3use ifc_model::EntityId;
4use ifc_schema::SchemaVersion;
5use thiserror::Error;
6
7/// Constraint projection or authoring failure.
8#[derive(Debug, Clone, PartialEq, Error)]
9#[non_exhaustive]
10pub enum ConstraintError {
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 with no bundled table, so no
115    /// layout can be trusted.
116    #[error("the header declares {schema}, which has no bundled table")]
117    UnsupportedSchema {
118        /// The `FILE_SCHEMA` token as written.
119        schema: String,
120    },
121    /// The model's release requires an attribute the authoring call leaves
122    /// unset, such as the IFC2X3 `IfcRoot.OwnerHistory` or the IFC2X3
123    /// `IfcRelAssociatesConstraint.Intent`.
124    #[error("cannot author {entity}: {schema:?} requires {attribute}")]
125    AuthoringRequired {
126        /// The entity type being authored.
127        entity: &'static str,
128        /// The required attribute, as the release names it.
129        attribute: &'static str,
130        /// The release the model declares.
131        schema: SchemaVersion,
132    },
133}
134
135/// Result alias for constraint operations.
136pub type ConstraintResult<T> = Result<T, ConstraintError>;