use ifc_model::{Entity, EntityId, Model, Value};
pub mod slot {
pub const GLOBAL_ID: usize = 0;
pub const NAME: usize = 2;
pub const OBJECT_TYPE: usize = 4;
pub const IDENTIFICATION: usize = 5;
pub const LONG_DESCRIPTION: usize = 6;
pub const PREDEFINED_TYPE: usize = 7;
pub const EVENT_TRIGGER_TYPE: usize = 8;
pub const USER_DEFINED_EVENT_TRIGGER_TYPE: usize = 9;
pub const EVENT_OCCURENCE_TIME: usize = 10;
}
pub mod time_slot {
pub const NAME: usize = 0;
pub const ACTUAL_DATE: usize = 3;
pub const EARLY_DATE: usize = 4;
pub const LATE_DATE: usize = 5;
pub const SCHEDULE_DATE: usize = 6;
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EventTime {
pub id: EntityId,
pub actual: Option<String>,
pub early: Option<String>,
pub late: Option<String>,
pub scheduled: Option<String>,
}
#[derive(Debug, Clone, Copy)]
pub struct Event<'m> {
id: EntityId,
entity: &'m Entity,
}
impl<'m> Event<'m> {
#[must_use]
pub fn id(&self) -> EntityId {
self.id
}
#[must_use]
pub fn name(&self) -> Option<&'m str> {
self.entity.text(slot::NAME)
}
#[must_use]
pub fn identification(&self) -> Option<&'m str> {
self.entity.text(slot::IDENTIFICATION)
}
#[must_use]
pub fn long_description(&self) -> Option<&'m str> {
self.entity.text(slot::LONG_DESCRIPTION)
}
#[must_use]
pub fn predefined_type(&self) -> Option<&'m str> {
match self.entity.attribute(slot::PREDEFINED_TYPE)? {
Value::Enum(token) => Some(token),
_ => None,
}
}
#[must_use]
pub fn trigger_type(&self) -> Option<&'m str> {
match self.entity.attribute(slot::EVENT_TRIGGER_TYPE)? {
Value::Enum(token) => Some(token),
_ => None,
}
}
#[must_use]
pub fn time(&self, model: &Model) -> Option<EventTime> {
let id = match self.entity.attribute(slot::EVENT_OCCURENCE_TIME)? {
Value::Ref(id) => *id,
_ => return None,
};
let entity = model.get(id)?;
if !entity.type_name.eq_ignore_ascii_case("IFCEVENTTIME") {
return None;
}
Some(EventTime {
id,
actual: entity.text(time_slot::ACTUAL_DATE).map(str::to_string),
early: entity.text(time_slot::EARLY_DATE).map(str::to_string),
late: entity.text(time_slot::LATE_DATE).map(str::to_string),
scheduled: entity.text(time_slot::SCHEDULE_DATE).map(str::to_string),
})
}
}
#[must_use]
pub fn events(model: &Model) -> Vec<Event<'_>> {
model
.of_type("IFCEVENT")
.map(|(id, entity)| Event { id, entity })
.collect()
}