use alloc::vec::Vec;
use crate::{codecs::Encoding, VerificationError, VerificationResult};
pub trait NargSerialize {
fn serialize_into_narg(&self, dst: &mut Vec<u8>);
fn serialize_into_new_narg(&self) -> impl AsRef<[u8]> {
let mut buf = alloc::vec::Vec::new();
self.serialize_into_narg(&mut buf);
buf.into_boxed_slice()
}
}
pub trait NargDeserialize: Sized {
fn deserialize_from_narg(buf: &mut &[u8]) -> VerificationResult<Self>;
}
impl<T: Encoding<[u8]>> NargSerialize for T {
fn serialize_into_narg(&self, dst: &mut Vec<u8>) {
dst.extend_from_slice(self.encode().as_ref());
}
}
impl<const N: usize> NargDeserialize for [u8; N] {
fn deserialize_from_narg(buf: &mut &[u8]) -> VerificationResult<Self> {
if buf.len() < N {
return Err(VerificationError);
}
let (head, tail) = buf.split_at(N);
*buf = tail;
Ok(head.try_into().unwrap())
}
}
impl<const N: usize, T: NargDeserialize> NargDeserialize for [T; N] {
fn deserialize_from_narg(buf: &mut &[u8]) -> VerificationResult<Self> {
let mut rest = *buf;
let vec: Vec<T> = (0..N)
.map(|_| T::deserialize_from_narg(&mut rest))
.collect::<Result<Vec<_>, _>>()?;
*buf = rest;
Ok(vec.try_into().unwrap_or_else(|_| unreachable!()))
}
}
impl NargDeserialize for u32 {
fn deserialize_from_narg(buf: &mut &[u8]) -> VerificationResult<Self> {
NargDeserialize::deserialize_from_narg(buf).map(Self::from_le_bytes)
}
}