use anyhow::{anyhow, Result};
use bytecheck::CheckBytes;
use rkyv::ser::serializers::AllocSerializer;
use rkyv::ser::Serializer;
use rkyv::validation::validators::DefaultValidator;
use rkyv::{archived_root, check_archived_root, Archive, Archived, Deserialize, Serialize};
use std::marker::PhantomData;
use std::sync::Arc;
fn archive<T>(t: &T) -> Vec<u8>
where
T: Serialize<AllocSerializer<256>>,
{
let mut ser = AllocSerializer::<256>::default();
ser.serialize_value(t).unwrap();
ser.into_serializer().into_inner().to_vec()
}
#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Ref<T> {
marker: PhantomData<T>,
bytes: Arc<[u8]>,
}
impl<T: Archive> Ref<T> {
pub fn new(bytes: Arc<[u8]>) -> Self {
Self {
marker: PhantomData,
bytes,
}
}
pub fn checked<'a>(buffer: &'a [u8]) -> Result<Self>
where
Archived<T>: CheckBytes<DefaultValidator<'a>> + 'static,
{
check_archived_root::<T>(buffer).map_err(|err| anyhow!("{}", err))?;
Ok(Self::new(buffer.into()))
}
pub fn archive(t: &T) -> Self
where
T: Serialize<AllocSerializer<256>>,
{
Self::new(archive(t).into())
}
pub fn to_owned(&self) -> Result<T>
where
Archived<T>: Deserialize<T, rkyv::Infallible>,
{
Ok(self.as_ref().deserialize(&mut rkyv::Infallible)?)
}
pub fn as_bytes(&self) -> &[u8] {
&self.bytes
}
pub fn as_arc(&self) -> &Arc<[u8]> {
&self.bytes
}
}
impl<T: Archive> AsRef<Archived<T>> for Ref<T> {
fn as_ref(&self) -> &Archived<T> {
unsafe { archived_root::<T>(&self.bytes[..]) }
}
}
impl<T: Archive> From<&Vec<u8>> for Ref<T> {
fn from(bytes: &Vec<u8>) -> Self {
Self::from(bytes.as_slice())
}
}
impl<T: Archive> From<&[u8]> for Ref<T> {
fn from(bytes: &[u8]) -> Self {
Self::new(bytes.into())
}
}
impl<T> From<Ref<T>> for Arc<[u8]> {
fn from(r: Ref<T>) -> Self {
r.bytes
}
}
impl<T> From<Ref<T>> for Vec<u8> {
fn from(r: Ref<T>) -> Self {
r.bytes.to_vec()
}
}
impl<T: Archive> std::fmt::Debug for Ref<T>
where
Archived<T>: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.as_ref())
}
}
impl<T: Archive> std::fmt::Display for Ref<T>
where
Archived<T>: std::fmt::Display,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_ref())
}
}