Skip to main content

ifc_element_type/
error.rs

1//! Why a type definition was refused.
2
3use ifc_model::EntityId;
4use ifc_schema::SchemaVersion;
5
6/// Why a type definition was refused.
7#[derive(Debug, Clone, PartialEq, Eq)]
8#[non_exhaustive]
9pub enum ElementTypeError {
10    /// An attribute value the schema does not permit.
11    Invalid {
12        /// STEP type name.
13        entity: &'static str,
14        /// Attribute that was rejected.
15        attribute: &'static str,
16        /// The offending value.
17        value: String,
18    },
19    /// The model's header declares several schemas; authoring binds to
20    /// exactly one release.
21    MultipleSchemas {
22        /// Number of `FILE_SCHEMA` declarations.
23        schemas: usize,
24    },
25    /// The model's header declares one schema with no bundled table, so no
26    /// layout can be trusted.
27    UnsupportedSchema {
28        /// The `FILE_SCHEMA` token as written.
29        schema: String,
30    },
31    /// The model's release does not declare the type, or declares it
32    /// abstract, such as `IfcDoorType` (IFC4 on) in an IFC2X3 model.
33    EntityNotInSchema {
34        /// STEP type name.
35        entity: &'static str,
36        /// The release the model declares.
37        schema: SchemaVersion,
38    },
39    /// A value for an attribute the model's release does not declare, such
40    /// as a `PredefinedType` for an IFC2X3 type that has none. It is
41    /// refused rather than dropped.
42    AuthoringNotInSchema {
43        /// STEP type name.
44        entity: &'static str,
45        /// The attribute.
46        attribute: &'static str,
47        /// The release the model declares.
48        schema: SchemaVersion,
49    },
50    /// The model's release requires an attribute the call leaves unset,
51    /// such as the IFC2X3 `IfcRoot.OwnerHistory`.
52    AuthoringRequired {
53        /// STEP type name.
54        entity: &'static str,
55        /// The required attribute, as the release names it.
56        attribute: &'static str,
57        /// The release the model declares.
58        schema: SchemaVersion,
59    },
60    /// A referenced entity, such as the owner history, resolves neither in
61    /// the model nor on the transaction.
62    MissingEntity {
63        /// The dangling id.
64        id: EntityId,
65    },
66}
67
68impl std::fmt::Display for ElementTypeError {
69    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70        match self {
71            Self::Invalid {
72                entity,
73                attribute,
74                value,
75            } => write!(f, "{entity}.{attribute}: {value}"),
76            Self::MultipleSchemas { schemas } => write!(
77                f,
78                "the header declares {schemas} schemas; authoring binds to exactly one"
79            ),
80            Self::UnsupportedSchema { schema } => {
81                write!(
82                    f,
83                    "the header declares {schema}, which has no bundled table"
84                )
85            }
86            Self::EntityNotInSchema { entity, schema } => {
87                write!(f, "{entity} is not an instantiable entity of {schema:?}")
88            }
89            Self::AuthoringNotInSchema {
90                entity,
91                attribute,
92                schema,
93            } => write!(
94                f,
95                "cannot author {entity}.{attribute}: not defined by {schema:?}"
96            ),
97            Self::AuthoringRequired {
98                entity,
99                attribute,
100                schema,
101            } => write!(f, "cannot author {entity}: {schema:?} requires {attribute}"),
102            Self::MissingEntity { id } => write!(f, "entity #{} does not exist", id.0),
103        }
104    }
105}
106
107impl std::error::Error for ElementTypeError {}
108
109/// Result of staging a type definition.
110pub type ElementTypeResult<T> = Result<T, ElementTypeError>;