use super::Index3D;
use crate::{
persistence::{MetaFields, PayloadError, write_index_container},
triangle::{Triangle3, records_as_bytes},
};
pub struct Serializer3D<'a> {
index: &'a Index3D,
interleaved: bool,
payloads: Option<Vec<&'a [u8]>>,
record_stride: Option<u32>,
meta: MetaFields<'a>,
}
impl<'a> Serializer3D<'a> {
pub(super) fn new(index: &'a Index3D) -> Self {
Self {
index,
interleaved: false,
payloads: None,
record_stride: None,
meta: MetaFields::default(),
}
}
pub fn payloads<P: AsRef<[u8]>>(mut self, payloads: &'a [P]) -> Self {
self.payloads = Some(payloads.iter().map(|p| p.as_ref()).collect());
self
}
pub fn records(mut self, stride: usize, flat: &'a [u8]) -> Self {
self.record_stride = Some(stride as u32);
self.payloads = Some(if stride == 0 {
Vec::new()
} else {
flat.chunks_exact(stride).collect()
});
self
}
pub fn triangles<T: Triangle3>(self, triangles: &'a [T]) -> Self {
let bytes = records_as_bytes(triangles);
self.records(T::STRIDE, bytes)
}
#[cfg(feature = "stream")]
pub fn interleaved(mut self) -> Self {
self.interleaved = true;
self
}
pub fn crs(mut self, crs: &'a str) -> Self {
self.meta.crs = Some(crs);
self
}
pub fn content_type(mut self, content_type: &'a str) -> Self {
self.meta.content_type = Some(content_type);
self
}
pub fn attribution(mut self, attribution: &'a str) -> Self {
self.meta.attribution = Some(attribution);
self
}
pub fn to_bytes(self) -> Result<Vec<u8>, PayloadError> {
let mut out = Vec::new();
self.to_bytes_into(&mut out)?;
Ok(out)
}
pub fn to_bytes_into(self, out: &mut Vec<u8>) -> Result<(), PayloadError> {
let idx = self.index;
let interleaved = self.interleaved;
let record_stride = self.record_stride;
write_index_container(
out,
3,
8,
interleaved,
idx.num_items,
idx.entries.len(),
idx.node_size,
|bytes| {
#[cfg(feature = "stream")]
if interleaved {
bytes.write_interleaved_3d(&idx.entries, &idx.indices);
return;
}
bytes.write_box3d_slice(&idx.entries);
bytes.write_usize_slice_as_u64(&idx.indices);
},
self.payloads.as_deref(),
record_stride,
&idx.indices[..idx.num_items],
&self.meta,
)
}
}