pub trait Codec<T = [u8]>:
crate::NargDeserialize + crate::NargSerialize + Encoding<T> + Decoding<T>
where
T: ?Sized,
{
}
pub trait Encoding<T = [u8]>
where
T: ?Sized,
{
fn encode(&self) -> impl AsRef<T>;
}
pub trait Decoding<T = [u8]>
where
T: ?Sized,
{
type Repr: Default + AsMut<T>;
fn decode(buf: Self::Repr) -> Self;
}
impl<U, T> Encoding<U> for &T
where
U: ?Sized,
T: Encoding<U> + ?Sized,
{
fn encode(&self) -> impl AsRef<U> {
(*self).encode()
}
}
impl<U: Clone, T: Encoding<[U]>, const N: usize> Encoding<[U]> for [T; N] {
fn encode(&self) -> impl AsRef<[U]> {
let mut output = alloc::vec::Vec::new();
for element in self {
output.extend_from_slice(element.encode().as_ref());
}
output
}
}
macro_rules! impl_int_encoding {
($type: ty) => {
impl Encoding<[u8]> for $type {
fn encode(&self) -> impl AsRef<[u8]> {
self.to_le_bytes()
}
}
};
}
macro_rules! impl_int_decoding {
($type: ty) => {
impl Decoding<[u8]> for $type {
type Repr = ByteArray<{ core::mem::size_of::<$type>() }>;
fn decode(buf: Self::Repr) -> Self {
<$type>::from_le_bytes(Decoding::decode(buf))
}
}
};
}
impl_int_encoding!(u8);
impl_int_decoding!(u8);
impl_int_encoding!(u16);
impl_int_decoding!(u16);
impl_int_encoding!(u32);
impl_int_decoding!(u32);
impl_int_encoding!(u64);
impl_int_decoding!(u64);
impl_int_encoding!(u128);
impl_int_decoding!(u128);
#[derive(Debug, Clone)]
pub struct ByteArray<const N: usize>([u8; N]);
impl<const N: usize> Default for ByteArray<N> {
fn default() -> Self {
Self([0; N])
}
}
impl<const N: usize> AsRef<[u8; N]> for ByteArray<N> {
fn as_ref(&self) -> &[u8; N] {
&self.0
}
}
impl<const N: usize> AsMut<[u8]> for ByteArray<N> {
fn as_mut(&mut self) -> &mut [u8] {
self.0.as_mut()
}
}
impl<const N: usize> Decoding<[u8]> for [u8; N] {
type Repr = ByteArray<N>;
fn decode(buf: Self::Repr) -> Self {
buf.0
}
}
impl Encoding<[u8]> for [u8] {
fn encode(&self) -> impl AsRef<[u8]> {
self
}
}
impl Encoding<[u8]> for str {
fn encode(&self) -> impl AsRef<[u8]> {
let len: u32 = self
.len()
.try_into()
.expect("string encoding requires length to fit in u32");
let mut out = alloc::vec::Vec::new();
out.extend_from_slice(&len.to_le_bytes());
out.extend_from_slice(self.as_bytes());
out
}
}
impl<U: Clone, T: Encoding<[U]>> Encoding<[U]> for alloc::vec::Vec<T> {
fn encode(&self) -> impl AsRef<[U]> {
let mut out = alloc::vec::Vec::new();
for x in self {
out.extend_from_slice(x.encode().as_ref());
}
out
}
}
impl<A, B> Encoding<[u8]> for (A, B)
where
A: Encoding<[u8]>,
B: Encoding<[u8]>,
{
fn encode(&self) -> impl AsRef<[u8]> {
let mut output = alloc::vec::Vec::new();
output.extend_from_slice(self.0.encode().as_ref());
output.extend_from_slice(self.1.encode().as_ref());
output
}
}
impl<A, B, C> Encoding<[u8]> for (A, B, C)
where
A: Encoding<[u8]>,
B: Encoding<[u8]>,
C: Encoding<[u8]>,
{
fn encode(&self) -> impl AsRef<[u8]> {
let mut output = alloc::vec::Vec::new();
output.extend_from_slice(self.0.encode().as_ref());
output.extend_from_slice(self.1.encode().as_ref());
output.extend_from_slice(self.2.encode().as_ref());
output
}
}
impl<T, E> Codec<T> for E
where
T: ?Sized,
E: crate::NargDeserialize + crate::NargSerialize + Encoding<T> + Decoding<T>,
{
}