use rkyv::{
Archive, Deserialize, Portable, Serialize,
api::high::{HighDeserializer, HighSerializer, HighValidator},
bytecheck::CheckBytes,
rancor,
ser::allocator::ArenaHandle,
util::AlignedVec,
};
use crate::{Error, ErrorKind};
pub type Serializer<'a> = HighSerializer<AlignedVec, ArenaHandle<'a>, rancor::Error>;
pub type Deserializer = HighDeserializer<rancor::Error>;
pub type Validator<'a> = HighValidator<'a, rancor::Error>;
#[derive(Debug)]
pub struct OwnedArchive<A> {
raw: AlignedVec,
archive: std::marker::PhantomData<A>,
}
impl<A> OwnedArchive<A>
where
A: Archive + for<'a> Serialize<Serializer<'a>>,
A::Archived: Portable + Deserialize<A, Deserializer> + for<'a> CheckBytes<Validator<'a>>,
{
pub fn new(raw: AlignedVec) -> Result<Self, Error> {
let _ = rkyv::access::<A::Archived, rancor::Error>(&raw)
.map_err(|e| ErrorKind::ArchiveRead(e.to_string()))?;
Ok(Self {
raw,
archive: std::marker::PhantomData,
})
}
pub fn from_reader<R: std::io::Read>(mut rdr: R) -> Result<Self, Error> {
let mut buf = AlignedVec::with_capacity(1024);
buf.extend_from_reader(&mut rdr).map_err(ErrorKind::Io)?;
Self::new(buf)
}
pub fn from_unarchived(unarchived: &A) -> Result<Self, Error> {
let raw = rkyv::to_bytes::<rancor::Error>(unarchived)
.map_err(|e| ErrorKind::ArchiveWrite(e.to_string()))?;
Ok(Self {
raw,
archive: std::marker::PhantomData,
})
}
pub fn write<W: std::io::Write>(this: &Self, mut wtr: W) -> Result<(), Error> {
Ok(wtr.write_all(&this.raw).map_err(ErrorKind::Io)?)
}
pub fn as_bytes(this: &Self) -> &[u8] {
&this.raw
}
pub fn deserialize(this: &Self) -> A {
rkyv::deserialize(&**this).expect("valid archive must deserialize correctly")
}
}
impl<A> std::ops::Deref for OwnedArchive<A>
where
A: Archive + for<'a> Serialize<Serializer<'a>>,
A::Archived: Portable + Deserialize<A, Deserializer> + for<'a> CheckBytes<Validator<'a>>,
{
type Target = A::Archived;
fn deref(&self) -> &A::Archived {
#[allow(unsafe_code)]
unsafe {
rkyv::access_unchecked::<A::Archived>(&self.raw)
}
}
}