use ifc_model::EntityId;
use crate::view::{borrowed_entity, required_refs, required_text, ClassificationView};
use crate::{ClassificationError, ClassificationResult};
const NOTATION: &str = "IFCCLASSIFICATIONNOTATION";
const FACET: &str = "IFCCLASSIFICATIONNOTATIONFACET";
borrowed_entity!(ClassificationNotation, "IFCCLASSIFICATIONNOTATION");
impl ClassificationNotation<'_> {
pub fn facet_ids(self) -> ClassificationResult<Vec<EntityId>> {
required_refs(
NOTATION,
self.id(),
self.entity(),
self.slot("NotationFacets")?,
"NotationFacets",
)
}
}
impl<'m> ClassificationView<'m> {
pub fn notations(self) -> impl Iterator<Item = ClassificationNotation<'m>> + 'm {
self.model()
.of_type(NOTATION)
.map(move |(id, e)| ClassificationNotation::from_known(id, e, self.release()))
}
pub fn notation(self, id: EntityId) -> ClassificationResult<ClassificationNotation<'m>> {
let entity = self
.model()
.get(id)
.ok_or(ClassificationError::UnknownEntity { id })?;
let notation = ClassificationNotation::try_bound(id, entity, self.release())?;
notation.slot("NotationFacets")?;
Ok(notation)
}
pub fn notation_values(self, id: EntityId) -> ClassificationResult<Vec<&'m str>> {
let notation = self.notation(id)?;
let mut values = Vec::new();
for facet_id in notation.facet_ids()? {
let facet =
self.model()
.get(facet_id)
.ok_or(ClassificationError::DanglingReference {
entity: NOTATION,
id,
attribute: "NotationFacets",
target: facet_id,
})?;
if !facet.is_type(FACET) {
return Err(ClassificationError::ReferenceType {
entity: NOTATION,
id,
attribute: "NotationFacets",
target: facet_id,
expected: "IfcClassificationNotationFacet",
actual: facet.type_name.to_string(),
});
}
let slot = self
.release()
.text_slot(FACET, facet_id, facet, "NotationValue")?;
values.push(required_text(
FACET,
facet_id,
facet,
slot,
"NotationValue",
)?);
}
Ok(values)
}
}