Skip to main content

ifc_classification/document/
reference.rs

1//! Borrowed `IfcDocumentReference` projection.
2use crate::view::{borrowed_entity, optional_ref, optional_text, ClassificationView};
3use crate::{ClassificationError, ClassificationResult};
4borrowed_entity!(DocumentReference, "IFCDOCUMENTREFERENCE");
5impl<'m> DocumentReference<'m> {
6    /// The `Location` (e.g. a URI) of the referenced document, when authored.
7    pub fn location(self) -> ClassificationResult<Option<&'m str>> {
8        optional_text(
9            "IFCDOCUMENTREFERENCE",
10            self.id(),
11            self.entity(),
12            self.text_slot("Location")?,
13            "Location",
14        )
15    }
16    /// The `Identification` code of the referenced document, when authored.
17    pub fn identification(self) -> ClassificationResult<Option<&'m str>> {
18        optional_text(
19            "IFCDOCUMENTREFERENCE",
20            self.id(),
21            self.entity(),
22            self.text_slot("Identification")?,
23            "Identification",
24        )
25    }
26    /// The `Name` of the referenced document; mutually exclusive with `referenced_document_id`.
27    pub fn name(self) -> ClassificationResult<Option<&'m str>> {
28        optional_text(
29            "IFCDOCUMENTREFERENCE",
30            self.id(),
31            self.entity(),
32            self.text_slot("Name")?,
33            "Name",
34        )
35    }
36    /// The `Description` of the referenced document, when authored.
37    pub fn description(self) -> ClassificationResult<Option<&'m str>> {
38        optional_text(
39            "IFCDOCUMENTREFERENCE",
40            self.id(),
41            self.entity(),
42            self.text_slot("Description")?,
43            "Description",
44        )
45    }
46    /// Id of the `ReferencedDocument` (an `IfcDocumentInformation`); mutually exclusive with `name`.
47    pub fn referenced_document_id(self) -> ClassificationResult<Option<ifc_model::EntityId>> {
48        optional_ref(
49            "IFCDOCUMENTREFERENCE",
50            self.id(),
51            self.entity(),
52            self.slot("ReferencedDocument")?,
53            "ReferencedDocument",
54        )
55    }
56    /// Checks `IfcExternalReference.WR1` (at least one of `Location`, `Identification`, `Name` stated) and the local `WR1` rule that exactly one of `Name` and `ReferencedDocument` is stated.
57    pub fn validate(self) -> ClassificationResult<()> {
58        if self.location()?.is_none() && self.identification()?.is_none() && self.name()?.is_none()
59        {
60            return Err(ClassificationError::InvalidValue {
61                entity: "IFCDOCUMENTREFERENCE",
62                id: self.id(),
63                attribute: "IfcExternalReference.WR1",
64                value: "Location, Identification, and Name are all unstated".into(),
65            });
66        }
67        if self.name()?.is_some() ^ self.referenced_document_id()?.is_some() {
68            Ok(())
69        } else {
70            Err(ClassificationError::InvalidValue {
71                entity: "IFCDOCUMENTREFERENCE",
72                id: self.id(),
73                attribute: "WR1",
74                value: "exactly one of Name and ReferencedDocument must be stated".into(),
75            })
76        }
77    }
78}
79impl<'m> ClassificationView<'m> {
80    /// All `IfcDocumentReference` instances in the model.
81    pub fn document_references(self) -> impl Iterator<Item = DocumentReference<'m>> + 'm {
82        self.model()
83            .of_type("IFCDOCUMENTREFERENCE")
84            .map(move |(id, e)| DocumentReference::from_known(id, e, self.release()))
85    }
86}