Skip to main content

ifc_style/
error.rs

1//! Typed failures while projecting or authoring presentation data.
2
3use ifc_model::EntityId;
4use thiserror::Error;
5
6/// A malformed, unresolved, or unsupported presentation contract.
7#[derive(Debug, Clone, PartialEq, Error)]
8#[non_exhaustive]
9pub enum StyleError {
10    /// An entity id was looked up but the model does not contain it.
11    #[error("entity {id} does not exist")]
12    UnknownEntity {
13        /// The id that resolved to nothing.
14        id: EntityId,
15    },
16    /// An entity was read as one IFC type but is actually another.
17    #[error("expected {expected}, found {actual} at {id}")]
18    WrongEntityType {
19        /// The entity that was read.
20        id: EntityId,
21        /// The IFC type the caller expected.
22        expected: &'static str,
23        /// The IFC type actually declared.
24        actual: String,
25    },
26    /// The active schema does not declare the requested entity type.
27    #[error("schema {schema} does not declare {entity}")]
28    UnsupportedEntity {
29        /// The schema's name.
30        schema: String,
31        /// The entity type name that is undeclared.
32        entity: &'static str,
33    },
34    /// The schema is a recognised IFC release whose layout this projection
35    /// is not verified for.
36    #[error("schema {schema} is not a release this projection is verified for")]
37    UnsupportedSchema {
38        /// The schema's name.
39        schema: String,
40    },
41    /// A mandatory attribute was absent, so the value cannot be inferred.
42    #[error("{entity} {id} is missing required attribute {attribute}")]
43    MissingAttribute {
44        /// The entity's IFC type.
45        entity: String,
46        /// The entity that was read.
47        id: EntityId,
48        /// Schema name of the attribute.
49        attribute: &'static str,
50    },
51    /// An attribute was present but held the wrong kind of value.
52    #[error("{entity} {id} has invalid {attribute}: {value}")]
53    InvalidValue {
54        /// The entity's IFC type.
55        entity: String,
56        /// The entity that was read.
57        id: EntityId,
58        /// Schema name of the attribute.
59        attribute: &'static str,
60        /// Debug-formatted offending value.
61        value: String,
62    },
63    /// The active schema declares the entity but not the requested attribute slot.
64    #[error("entity {entity} in schema {schema} has no attribute {attribute}")]
65    UnsupportedAttribute {
66        /// The schema's name.
67        schema: String,
68        /// The entity type name.
69        entity: &'static str,
70        /// The attribute name that is undeclared.
71        attribute: &'static str,
72    },
73    /// A reference attribute pointed at an entity id the model does not contain.
74    #[error("reference {target} from {source_id} does not resolve")]
75    DanglingReference {
76        /// The entity holding the dangling reference.
77        source_id: EntityId,
78        /// The id that resolved to nothing.
79        target: EntityId,
80    },
81    /// A reference resolved, but the target is not the IFC type (or select
82    /// member) the referencing slot requires.
83    #[error("reference {target} has type {actual}, expected {expected}")]
84    ReferenceType {
85        /// The entity that was read.
86        target: EntityId,
87        /// The IFC type (or select) the slot requires.
88        expected: &'static str,
89        /// The IFC type actually declared.
90        actual: String,
91    },
92    /// An authoring helper was given a value it cannot encode for the target attribute.
93    #[error("cannot author {entity}.{attribute}: {value}")]
94    AuthoringInvalid {
95        /// The IFC entity type being authored.
96        entity: &'static str,
97        /// The attribute being set.
98        attribute: &'static str,
99        /// Debug-formatted offending value.
100        value: String,
101    },
102    /// A normalized-ratio or bounded measure fell outside its required range.
103    #[error("{entity} {id}.{attribute} is outside [{minimum}, {maximum}]: {value}")]
104    OutOfRange {
105        /// The measure's IFC type, e.g. `"IfcNormalisedRatioMeasure"`.
106        entity: &'static str,
107        /// The entity that was read.
108        id: EntityId,
109        /// Schema name of the attribute.
110        attribute: &'static str,
111        /// The out-of-range value.
112        value: f64,
113        /// The inclusive lower bound.
114        minimum: f64,
115        /// The inclusive upper bound.
116        maximum: f64,
117    },
118    /// More than one `IfcStyledItem` directly assigned styles to the same
119    /// representation item; cascade resolution refuses to guess a winner.
120    #[error("representation item {item} has {count} direct styled-item assignments")]
121    AmbiguousStyleAssignment {
122        /// The representation item with conflicting direct assignments.
123        item: EntityId,
124        /// The number of conflicting `IfcStyledItem`s found.
125        count: usize,
126    },
127}
128
129/// The result type returned by this crate's projection and authoring operations.
130pub type StyleResult<T> = Result<T, StyleError>;