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>;