mod decode;
mod issue;
mod series;
mod table;
use ifc_model::{EntityId, Model};
use ifc_schema::{Schema, SchemaVersion};
use crate::error::{TabularReadError, TabularReadResult};
pub use issue::TabularIssue;
pub use series::{SeriesValue, TimeSeries, TimeSeriesKind};
pub use table::{Table, TableColumn, TableRow};
#[derive(Debug, Clone, Copy)]
pub struct TabularView<'m> {
model: &'m Model,
schema: &'m Schema,
}
impl<'m> TabularView<'m> {
pub fn new(model: &'m Model, schema: &'m Schema) -> TabularReadResult<Self> {
match schema.version() {
Some(SchemaVersion::Ifc4 | SchemaVersion::Ifc4x3) => Ok(Self { model, schema }),
_ => Err(TabularReadError::UnsupportedSchema {
schema: schema.name().to_owned(),
}),
}
}
#[must_use]
pub fn table_ids(self) -> &'m [EntityId] {
self.model.ids_of_type(table::TABLE)
}
#[must_use]
pub fn series_ids(self) -> Vec<EntityId> {
let mut ids = self.model.ids_of_type(series::REGULAR).to_vec();
ids.extend_from_slice(self.model.ids_of_type(series::IRREGULAR));
ids
}
pub fn table(self, id: EntityId) -> TabularReadResult<Table<'m>> {
let entity = self
.model
.get(id)
.ok_or(TabularReadError::UnknownEntity { id })?;
if !entity.is_type(table::TABLE) {
return Err(TabularReadError::WrongEntityType {
id,
expected: "IFCTABLE",
actual: entity.type_name.to_string(),
});
}
Ok(table::read_table(self.model, self.schema, id, entity))
}
pub fn time_series(self, id: EntityId) -> TabularReadResult<TimeSeries<'m>> {
let entity = self
.model
.get(id)
.ok_or(TabularReadError::UnknownEntity { id })?;
let type_name = if entity.is_type(series::REGULAR) {
series::REGULAR
} else if entity.is_type(series::IRREGULAR) {
series::IRREGULAR
} else {
return Err(TabularReadError::WrongEntityType {
id,
expected: "IFCREGULARTIMESERIES or IFCIRREGULARTIMESERIES",
actual: entity.type_name.to_string(),
});
};
Ok(series::read_series(
self.model,
self.schema,
id,
entity,
type_name,
))
}
}