ifc_properties/template/check/finding.rs
1//! What a template check reports.
2
3use std::sync::Arc;
4
5use ifc_model::EntityId;
6
7use crate::error::PropertyAnomaly;
8
9/// Which measure-type attribute of an `IfcSimplePropertyTemplate` a value
10/// was checked against.
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12#[non_exhaustive]
13pub enum MeasureRole {
14 /// `PrimaryMeasureType`.
15 Primary,
16 /// `SecondaryMeasureType`.
17 Secondary,
18}
19
20/// Why a check could not decide whether a set conforms to its template.
21///
22/// Each reason names something IFC leaves undefined or the file leaves
23/// unstated. The checker reports it rather than guessing either way.
24#[derive(Debug, Clone, PartialEq, Eq)]
25#[non_exhaustive]
26pub enum UndecidedReason {
27 /// A `TemplateType` constant that is not a member of the declared
28 /// release's enumeration, e.g. `Q_NUMBER` in an IFC4 file.
29 UnknownTemplateType {
30 /// The constant as written.
31 value: Arc<str>,
32 },
33 /// A `TemplateType` constant whose documentation in the declared release
34 /// does not say which entity it governs: IFC4X3 ADD2 documents
35 /// `Q_NUMBER` with "No description available".
36 UndocumentedTemplateType {
37 /// The constant.
38 value: Arc<str>,
39 },
40 /// A `PrimaryMeasureType` or `SecondaryMeasureType` that names no type
41 /// or entity the declared release declares.
42 UnknownMeasureType {
43 /// Which of the two.
44 measure: MeasureRole,
45 /// The label as written.
46 value: Arc<str>,
47 },
48 /// A value whose type cannot be read: a select member written without
49 /// its type, or a reference to an entity absent from the file.
50 UntypedValue {
51 /// The property attribute holding it, e.g. `NominalValue`.
52 attribute: &'static str,
53 },
54 /// A property template without a `Name`, which cannot be matched to any
55 /// property: templates are matched to properties by `Name` alone.
56 UnnamedTemplate,
57 /// An `ApplicableEntity` entry that names no entity of the declared
58 /// release, or does not follow the documented form
59 /// `IfcEntity[/PREDEFINEDTYPE][[PerformanceHistory]]`.
60 UnknownApplicableEntity {
61 /// The entry, trimmed.
62 entry: Arc<str>,
63 },
64 /// An `ApplicableEntity` entry qualified by a predefined type, on an
65 /// object of that entity whose own `PredefinedType` is unset,
66 /// `NOTDEFINED`, or not an attribute of its entity. The type object may
67 /// state it instead, and that is not followed here.
68 PredefinedTypeUnstated {
69 /// The entry, trimmed.
70 entry: Arc<str>,
71 },
72 /// An `ApplicableEntity` entry qualified by `[PerformanceHistory]` on an
73 /// `IfcPerformanceHistory`: the entry names the object the history is
74 /// assigned to by `IfcRelAssignsToControl`, which is not followed here.
75 PerformanceHistory {
76 /// The entry, trimmed.
77 entry: Arc<str>,
78 },
79 /// The templated set is a predefined property set (e.g.
80 /// `IfcDoorLiningProperties`), whose members are fixed attributes of its
81 /// entity rather than named properties; templates are documented for
82 /// `IfcPropertySet` and `IfcElementQuantity` only.
83 PredefinedSet {
84 /// The set's IFC type name.
85 found: Arc<str>,
86 },
87}
88
89/// One way a templated property set deviates from an
90/// `IfcPropertySetTemplate` linked to it by `IfcRelDefinesByTemplate`.
91///
92/// Every finding names the set and the set template; findings about one
93/// property also name the property and/or the (possibly nested) property
94/// template. A finding is a deviation from the in-file template, which is
95/// what the caller asked about; except where noted, IFC does not make it a
96/// schema violation.
97#[derive(Debug, Clone, PartialEq, Eq)]
98#[non_exhaustive]
99pub enum TemplateFinding {
100 /// A property template has no property of its `Name` in the set (or, for
101 /// a nested template, in the complex property).
102 MissingProperty {
103 /// The templated set.
104 set: EntityId,
105 /// The `IfcPropertySetTemplate`.
106 template: EntityId,
107 /// The set, or the complex property or quantity whose members were
108 /// compared.
109 container: EntityId,
110 /// The property template with no property.
111 property_template: EntityId,
112 /// Its `Name`.
113 name: Arc<str>,
114 },
115 /// A property whose `Name` no property template of the set template (or
116 /// of the complex template) states.
117 UnexpectedProperty {
118 /// The templated set.
119 set: EntityId,
120 /// The `IfcPropertySetTemplate`.
121 template: EntityId,
122 /// The set, or the complex property or quantity holding it.
123 container: EntityId,
124 /// The property or quantity.
125 property: EntityId,
126 /// Its `Name`.
127 name: Arc<str>,
128 },
129 /// A property whose entity is not the one its template's `TemplateType`
130 /// prescribes, e.g. an `IfcPropertySingleValue` where the template says
131 /// `P_ENUMERATEDVALUE`.
132 WrongForm {
133 /// The templated set.
134 set: EntityId,
135 /// The `IfcPropertySetTemplate`.
136 template: EntityId,
137 /// The property or quantity.
138 property: EntityId,
139 /// Its template.
140 property_template: EntityId,
141 /// The template's `TemplateType`; `None` when unset, when any simple
142 /// (for a simple template) or complex (for a complex one) property
143 /// or quantity is expected.
144 template_type: Option<Arc<str>>,
145 /// The entities any of which would conform (subtypes included).
146 expected: &'static [&'static str],
147 /// The property's IFC type name.
148 found: Arc<str>,
149 },
150 /// A value whose declared type is not the template's measure type.
151 WrongMeasureType {
152 /// The templated set.
153 set: EntityId,
154 /// The `IfcPropertySetTemplate`.
155 template: EntityId,
156 /// The property.
157 property: EntityId,
158 /// Its template.
159 property_template: EntityId,
160 /// Which measure type of the template applies.
161 measure: MeasureRole,
162 /// The property attribute checked, e.g. `NominalValue`.
163 attribute: &'static str,
164 /// The template's measure type, as written.
165 expected: Arc<str>,
166 /// The first nonconforming value's type, or the referenced entity's
167 /// type for a reference value.
168 found: Arc<str>,
169 },
170 /// The set is not the entity the template's `TemplateType` governs: a
171 /// `PSET_*` template on an `IfcElementQuantity`, a `QTO_*` template on
172 /// an `IfcPropertySet`, or (IFC4X3) a material- or profile-driven
173 /// template on any property set definition.
174 WrongSetKind {
175 /// The templated set.
176 set: EntityId,
177 /// The `IfcPropertySetTemplate`.
178 template: EntityId,
179 /// The template's `TemplateType`.
180 template_type: Arc<str>,
181 /// The entity the template type governs.
182 expected: &'static str,
183 /// The set's IFC type name.
184 found: Arc<str>,
185 },
186 /// The set sits on an object its template's `TemplateType` excludes: a
187 /// `*_TYPEDRIVENONLY` set on an occurrence, an `*_OCCURRENCEDRIVEN` set
188 /// on a type, a `PSET_PERFORMANCEDRIVEN` set on anything but an
189 /// `IfcPerformanceHistory`.
190 WrongAttachment {
191 /// The templated set.
192 set: EntityId,
193 /// The `IfcPropertySetTemplate`.
194 template: EntityId,
195 /// The object carrying the set.
196 object: EntityId,
197 /// The template's `TemplateType`.
198 template_type: Arc<str>,
199 /// The object's IFC type name.
200 found: Arc<str>,
201 },
202 /// The set sits on an object that no entry of the template's
203 /// `ApplicableEntity` admits.
204 OutsideApplicableEntity {
205 /// The templated set.
206 set: EntityId,
207 /// The `IfcPropertySetTemplate`.
208 template: EntityId,
209 /// The object carrying the set.
210 object: EntityId,
211 /// The object's IFC type name.
212 found: Arc<str>,
213 /// The template's `ApplicableEntity`, as written.
214 applicable_entity: Arc<str>,
215 },
216 /// Whether `subject` conforms cannot be decided from the file and the
217 /// release's documentation.
218 Undecided {
219 /// The templated set.
220 set: EntityId,
221 /// The `IfcPropertySetTemplate`.
222 template: EntityId,
223 /// What could not be decided: a property, a property template, the
224 /// set template, or an object carrying the set.
225 subject: EntityId,
226 /// Why.
227 reason: UndecidedReason,
228 },
229}
230
231/// Everything a template check found.
232#[derive(Debug, Clone, PartialEq, Default)]
233#[non_exhaustive]
234pub struct TemplateReport {
235 /// Deviations, grouped by set (ascending id), then template (ascending
236 /// id); within one pair, the set's kind, then its members in file
237 /// order, then its missing members in template order, then the objects
238 /// carrying it (ascending id).
239 pub findings: Vec<TemplateFinding>,
240 /// Malformed facts met while reading templates, sets and relationships.
241 /// A member or template left out because of one is not compared, so a
242 /// report with anomalies is not a proof of conformance.
243 pub anomalies: Vec<PropertyAnomaly>,
244}