byte_lamination 0.1.2

Type-readable byte transformation wrappers, with CBOR and BARE serialisation and Zstd compression.
Documentation
use crate::{AutoDelaminate, AutoDelaminateBorrowed, AutoLaminate, ByteLamination};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use std::borrow::Cow;
use std::error::Error;
use std::marker::PhantomData;

/// Wrapper that uses serde to perform CBOR serialisation on an arbitrary type.
#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct SerdeCbor<'a, T> {
    bytes: Cow<'a, [u8]>,
    _marker: PhantomData<T>,
}

impl<'a, T> From<Cow<'a, [u8]>> for SerdeCbor<'a, T> {
    fn from(bytes: Cow<'a, [u8]>) -> Self {
        Self {
            bytes,
            _marker: PhantomData::default(),
        }
    }
}

impl<'a, T> Into<Cow<'a, [u8]>> for SerdeCbor<'a, T> {
    fn into(self) -> Cow<'a, [u8]> {
        self.bytes
    }
}

impl<'a, T> ByteLamination<'a> for SerdeCbor<'a, T> {
    fn as_cow_bytes(&self) -> Cow<'_, [u8]> {
        Cow::Borrowed(&self.bytes)
    }

    fn into_bytes(self) -> Vec<u8> {
        self.bytes.into_owned()
    }

    fn try_from_bytes(bytes: Cow<'a, [u8]>) -> Result<Self, Box<dyn Error>> {
        Ok(Self::from(bytes))
    }
}

impl<'a, T: Serialize> SerdeCbor<'a, T> {
    pub fn serialise<'inp>(inner: &'inp T) -> Result<Self, Box<dyn Error>> {
        let cbor_bytes = serde_cbor::to_vec(inner)?;
        Ok(Self::from(Cow::Owned(cbor_bytes)))
    }
}

impl<'a, T: Deserialize<'a>> SerdeCbor<'a, T> {
    pub fn deserialise(&'a self) -> Result<T, Box<dyn Error>> {
        let deser_t = serde_cbor::from_slice(&self.bytes)?;
        Ok(deser_t)
    }
}

impl<'a, T: Serialize> AutoLaminate<T> for SerdeCbor<'a, T> {
    fn laminate(item: T) -> Result<Self, Box<dyn Error>> {
        Self::serialise(&item)
    }
}

impl<'a, T: Serialize> AutoLaminate<&T> for SerdeCbor<'a, T> {
    fn laminate(item: &T) -> Result<Self, Box<dyn Error>> {
        Self::serialise(item)
    }
}

impl<'a, T: DeserializeOwned> AutoDelaminate<T> for SerdeCbor<'a, T> {
    fn delaminate(self) -> Result<T, Box<dyn Error>> {
        self.deserialise()
    }
}

impl<'a, T: Deserialize<'a>> AutoDelaminateBorrowed<'a, T> for SerdeCbor<'a, T> {
    fn delaminate(&'a self) -> Result<T, Box<dyn Error>> {
        self.deserialise()
    }
}