use core::{marker::PhantomData, mem::MaybeUninit};
use alloc::vec::Vec;
use crate::{
format::Format,
unpack::{binary, collections::unpack_array_borrowed},
Error, Unpackable, UnpackableBorrowed,
};
impl<'a> UnpackableBorrowed<'a> for &'a [u8] {
type Error = Error;
fn unpack_with_ofs(buf: &'a [u8]) -> Result<(usize, Self), Self::Error> {
binary::unpack_bytes(buf)
}
}
impl<'a> UnpackableBorrowed<'a> for &'a str {
type Error = Error;
fn unpack_with_ofs(buf: &'a [u8]) -> Result<(usize, Self), Self::Error> {
binary::unpack_str(buf)
}
}
impl<'a, X> UnpackableBorrowed<'a> for PhantomData<X> {
type Error = Error;
fn unpack_with_ofs(buf: &'a [u8]) -> Result<(usize, Self), Self::Error> {
<PhantomData<X> as Unpackable>::unpack_with_ofs(buf)
}
}
impl<'a, X> UnpackableBorrowed<'a> for Option<X>
where
X: UnpackableBorrowed<'a>,
{
type Error = <X as UnpackableBorrowed<'a>>::Error;
fn unpack_with_ofs(buf: &'a [u8]) -> Result<(usize, Self), Self::Error> {
if buf.is_empty() {
return Err(Error::BufferTooShort.into());
}
if buf[0] == Format::NIL {
return Ok((1, None));
}
X::unpack_with_ofs(buf).map(|(n, x)| (n, Some(x)))
}
}
impl<'a, X> UnpackableBorrowed<'a> for Vec<X>
where
X: UnpackableBorrowed<'a>,
{
type Error = <X as UnpackableBorrowed<'a>>::Error;
fn unpack_with_ofs(buf: &'a [u8]) -> Result<(usize, Self), Self::Error> {
unpack_array_borrowed(buf)
}
}
macro_rules! unpackable {
($ty:ty) => {
impl<'a> UnpackableBorrowed<'a> for $ty {
type Error = Error;
fn unpack_with_ofs(buf: &'a [u8]) -> Result<(usize, Self), Self::Error> {
<$ty as Unpackable>::unpack_with_ofs(buf)
}
}
};
}
unpackable!(u8);
unpackable!(u16);
unpackable!(u32);
unpackable!(u64);
unpackable!(u128);
unpackable!(usize);
unpackable!(i8);
unpackable!(i16);
unpackable!(i32);
unpackable!(i64);
unpackable!(i128);
unpackable!(isize);
unpackable!(f32);
unpackable!(f64);
unpackable!(());
unpackable!(bool);
unpackable!(char);
macro_rules! array {
($n:expr) => {
impl<'a, X> UnpackableBorrowed<'a> for [X; $n]
where
X: UnpackableBorrowed<'a>,
{
type Error = <X as UnpackableBorrowed<'a>>::Error;
fn unpack_with_ofs(mut buf: &'a [u8]) -> Result<(usize, Self), Self::Error> {
let mut array = [const { MaybeUninit::uninit() }; $n];
let n =
array
.iter_mut()
.try_fold::<_, _, Result<_, Self::Error>>(0, |count, a| {
let (n, x) = X::unpack_with_ofs(buf)?;
buf = &buf[n..];
a.write(x);
Ok(count + n)
})?;
let array = ::core::array::from_fn(|i| {
let mut x = MaybeUninit::zeroed();
::core::mem::swap(&mut array[i], &mut x);
unsafe { MaybeUninit::assume_init(x) }
});
Ok((n, array))
}
}
};
}
array!(0);
array!(1);
array!(2);
array!(3);
array!(4);
array!(5);
array!(6);
array!(7);
array!(8);
array!(9);
array!(10);
array!(11);
array!(12);
array!(13);
array!(14);
array!(15);
array!(16);
array!(17);
array!(18);
array!(19);
array!(20);
array!(21);
array!(22);
array!(23);
array!(24);
array!(25);
array!(26);
array!(27);
array!(28);
array!(29);
array!(30);
array!(31);
array!(32);
array!(33);
array!(34);
array!(35);
array!(36);
array!(37);
array!(38);
array!(39);
array!(40);
array!(41);
array!(42);
array!(43);
array!(44);
array!(45);
array!(46);
array!(47);
array!(48);
array!(49);
array!(50);
array!(51);
array!(52);
array!(53);
array!(54);
array!(55);
array!(56);
array!(57);
array!(58);
array!(59);
array!(60);
array!(61);
array!(62);
array!(63);
array!(64);
macro_rules! tuple {
($err:ident, $($name:ident)+) => (
impl<'a, $($name,)+> UnpackableBorrowed<'a> for ($($name,)+)
where
$($name: UnpackableBorrowed<'a>,)+
$($err::Error: From<<$name as UnpackableBorrowed<'a>>::Error>,)+
{
type Error = <$err as UnpackableBorrowed<'a>>::Error;
#[allow(non_snake_case)]
fn unpack_with_ofs(mut buf: &'a [u8]) -> Result<(usize, Self), Self::Error> {
let mut n = 0;
$(let (c, $name) = $name::unpack_with_ofs(buf)?; n += c; buf = &buf[c..];)+
let _ = buf;
Ok((n, ($($name, )+)))
}
}
);
}
tuple! {
A, A
}
tuple! {
A, A B
}
tuple! {
A, A B C
}
tuple! {
A, A B C D
}
tuple! {
A, A B C D E
}
tuple! {
A, A B C D E F
}
tuple! {
A, A B C D E F G
}
tuple! {
A, A B C D E F G H
}
tuple! {
A, A B C D E F G H I
}
tuple! {
A, A B C D E F G H I J
}
tuple! {
A, A B C D E F G H I J K
}
tuple! {
A, A B C D E F G H I J K L
}
tuple! {
A, A B C D E F G H I J K L M
}
tuple! {
A, A B C D E F G H I J K L M N
}
tuple! {
A, A B C D E F G H I J K L M N O
}
tuple! {
A, A B C D E F G H I J K L M N O P
}
tuple! {
A, A B C D E F G H I J K L M N O P Q
}
tuple! {
A, A B C D E F G H I J K L M N O P Q R
}
tuple! {
A, A B C D E F G H I J K L M N O P Q R S
}
tuple! {
A, A B C D E F G H I J K L M N O P Q R S T
}
tuple! {
A, A B C D E F G H I J K L M N O P Q R S T U
}
tuple! {
A, A B C D E F G H I J K L M N O P Q R S T U V
}
tuple! {
A, A B C D E F G H I J K L M N O P Q R S T U V W
}
tuple! {
A, A B C D E F G H I J K L M N O P Q R S T U V W X
}
tuple! {
A, A B C D E F G H I J K L M N O P Q R S T U V W X Y
}
tuple! {
A, A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
}