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;
#[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()
}
}