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            0,
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            1,
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("IFCDOCUMENTREFERENCE", self.id(), self.entity(), 2, "Name")
29    }
30    /// The `Description` of the referenced document, when authored.
31    pub fn description(self) -> ClassificationResult<Option<&'m str>> {
32        optional_text(
33            "IFCDOCUMENTREFERENCE",
34            self.id(),
35            self.entity(),
36            3,
37            "Description",
38        )
39    }
40    /// Id of the `ReferencedDocument` (an `IfcDocumentInformation`); mutually exclusive with `name`.
41    pub fn referenced_document_id(self) -> ClassificationResult<Option<ifc_model::EntityId>> {
42        optional_ref(
43            "IFCDOCUMENTREFERENCE",
44            self.id(),
45            self.entity(),
46            4,
47            "ReferencedDocument",
48        )
49    }
50    /// 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.
51    pub fn validate(self) -> ClassificationResult<()> {
52        if self.location()?.is_none() && self.identification()?.is_none() && self.name()?.is_none()
53        {
54            return Err(ClassificationError::InvalidValue {
55                entity: "IFCDOCUMENTREFERENCE",
56                id: self.id(),
57                attribute: "IfcExternalReference.WR1",
58                value: "Location, Identification, and Name are all unstated".into(),
59            });
60        }
61        if self.name()?.is_some() ^ self.referenced_document_id()?.is_some() {
62            Ok(())
63        } else {
64            Err(ClassificationError::InvalidValue {
65                entity: "IFCDOCUMENTREFERENCE",
66                id: self.id(),
67                attribute: "WR1",
68                value: "exactly one of Name and ReferencedDocument must be stated".into(),
69            })
70        }
71    }
72}
73impl<'m> ClassificationView<'m> {
74    /// All `IfcDocumentReference` instances in the model.
75    pub fn document_references(self) -> impl Iterator<Item = DocumentReference<'m>> + 'm {
76        self.model()
77            .of_type("IFCDOCUMENTREFERENCE")
78            .map(|(id, e)| DocumentReference::from_known(id, e))
79    }
80}