use crate::{reader, writer, XmlProfile};
use ifc_model::{Codec, Model, ModelError};
#[derive(Default)]
pub struct XmlCodec {
profile: Option<XmlProfile>,
#[cfg(feature = "schema")]
schema: Option<std::sync::Arc<ifc_schema::Schema>>,
}
impl XmlCodec {
#[must_use]
pub const fn strict(profile: XmlProfile) -> Self {
Self {
profile: Some(profile),
#[cfg(feature = "schema")]
schema: None,
}
}
#[must_use]
pub const fn profile(&self) -> Option<XmlProfile> {
self.profile
}
#[cfg(feature = "schema")]
#[must_use]
pub fn with_schema(schema: std::sync::Arc<ifc_schema::Schema>) -> Self {
Self {
profile: None,
schema: Some(schema),
}
}
#[cfg(feature = "schema")]
#[must_use]
pub fn with_schema_and_profile(
schema: std::sync::Arc<ifc_schema::Schema>,
profile: XmlProfile,
) -> Self {
Self {
profile: Some(profile),
schema: Some(schema),
}
}
#[cfg(feature = "schema")]
#[must_use]
pub fn schema(&self) -> Option<&ifc_schema::Schema> {
self.schema.as_deref()
}
}
impl Codec for XmlCodec {
fn name(&self) -> &'static str {
"ifcXML"
}
fn extensions(&self) -> &'static [&'static str] {
&["ifcxml", "xml"]
}
fn detect(&self, bytes: &[u8]) -> bool {
reader::looks_like_xml(bytes)
}
fn read_bytes(&self, bytes: &[u8]) -> Result<Model, ModelError> {
reader::read(self, bytes).map_err(|error| ModelError::Syntax {
offset: 0,
detail: error.to_string(),
})
}
fn write(&self, model: &Model, out: &mut dyn std::io::Write) -> Result<(), ModelError> {
let bytes =
writer::write(self, model).map_err(|error| ModelError::Write(error.to_string()))?;
out.write_all(&bytes)
.map_err(|error| ModelError::Io(error.to_string()))
}
}