Skip to main content

ifc_material/
error.rs

1//! Typed failures while interpreting IFC material-resource entities.
2
3use ifc_model::EntityId;
4use thiserror::Error;
5
6/// A malformed, ambiguous, or unresolved material projection.
7#[derive(Debug, Clone, PartialEq, Error)]
8#[non_exhaustive]
9pub enum MaterialError {
10    /// A projection expected one entity type but the model holds another.
11    #[error("expected {expected}, found {actual}")]
12    WrongEntityType {
13        /// The IFC entity type name that was expected.
14        expected: &'static str,
15        /// The IFC entity type name actually found on the record.
16        actual: String,
17    },
18    /// A required attribute slot on the entity is absent (unset `$`).
19    #[error("{entity} {id} is missing required attribute {attribute}")]
20    MissingAttribute {
21        /// The IFC entity type name.
22        entity: &'static str,
23        /// The id of the entity missing the attribute.
24        id: EntityId,
25        /// The name of the missing attribute.
26        attribute: &'static str,
27    },
28    /// An attribute is present but its value violates a WHERE rule or type
29    /// constraint.
30    #[error("{entity} {id} has invalid {attribute}: {value}")]
31    InvalidValue {
32        /// The IFC entity type name.
33        entity: &'static str,
34        /// The id of the entity with the invalid attribute.
35        id: EntityId,
36        /// The name of the invalid attribute.
37        attribute: &'static str,
38        /// A rendering of the offending value.
39        value: String,
40    },
41    /// A value supplied to an authoring function cannot be written to the
42    /// named entity attribute.
43    #[error("cannot author {entity}.{attribute}: {value}")]
44    AuthoringInvalid {
45        /// The IFC entity type name being authored.
46        entity: &'static str,
47        /// The name of the attribute that rejected the value.
48        attribute: &'static str,
49        /// A rendering of the rejected value.
50        value: String,
51    },
52    /// An authoring-time reference points at an entity of the wrong type.
53    #[error("authoring reference {target} has type {actual}, expected {expected}")]
54    AuthoringReferenceType {
55        /// The id of the referenced entity.
56        target: EntityId,
57        /// The IFC entity type name that was expected.
58        expected: &'static str,
59        /// The IFC entity type name actually found at `target`.
60        actual: String,
61    },
62    /// A referenced entity id does not exist in the model.
63    #[error("entity {id} does not exist")]
64    UnknownEntity {
65        /// The id that could not be resolved.
66        id: EntityId,
67    },
68    /// A reference field points at an id absent from the model.
69    #[error("reference {target} from {source_id} does not resolve")]
70    DanglingReference {
71        /// The id of the entity holding the reference.
72        source_id: EntityId,
73        /// The unresolved target id.
74        target: EntityId,
75    },
76    /// A reference resolves to an entity, but of the wrong type.
77    #[error("reference {target} from {source_id} has type {actual}, expected {expected}")]
78    ReferenceType {
79        /// The id of the entity holding the reference.
80        source_id: EntityId,
81        /// The id of the referenced entity.
82        target: EntityId,
83        /// The IFC entity type name that was expected.
84        expected: &'static str,
85        /// The IFC entity type name actually found at `target`.
86        actual: String,
87    },
88    /// The object is directly related to more than one `IfcMaterial`
89    /// via `IfcRelAssociatesMaterial`, so the single active material cannot
90    /// be determined.
91    #[error("object {object} has {count} direct material assignments")]
92    AmbiguousAssignment {
93        /// The id of the object with conflicting assignments.
94        object: EntityId,
95        /// The number of direct material assignments found.
96        count: usize,
97    },
98    /// The object is typed by more than one `IfcTypeObject`, so its
99    /// inherited material cannot be determined unambiguously.
100    #[error("object {object} has {count} assigned IFC types")]
101    AmbiguousType {
102        /// The id of the object with conflicting type relationships.
103        object: EntityId,
104        /// The number of `IfcTypeObject` relationships found.
105        count: usize,
106    },
107}
108
109/// Convenience alias for results of material-projection operations.
110pub type MaterialResult<T> = Result<T, MaterialError>;