use super::{
pack::{Pack, Result as WriteResult, Target, Writer},
unpack::{Reader, Result as ReadResult, Unpack},
};
macro_rules! impl_for_numeric {
($size:literal, $t:ty) => {
impl Pack for $t {
fn pack<T: Target>(&self, writer: &mut Writer<T>) -> WriteResult<()> {
let bytes = self.to_be_bytes();
writer.write_bytes(&bytes[..])
}
}
impl<'a> Unpack<'a> for $t {
fn unpack(reader: &mut Reader<'a>) -> ReadResult<Self> {
let bytes = reader.read_bytes($size)?;
let mut buf = [0; $size];
bytes.copy_to_slice(&mut buf[..]);
Ok(Self::from_be_bytes(buf))
}
}
};
}
macro_rules! impl_for_numeric_multi {
($(($size:literal, $t:ty),)*) => {
$( impl_for_numeric!($size, $t); )*
}
}
macro_rules! impl_for_tuple {
($($v:ident $t:ident),*) => {
impl < $($t : Pack),* > Pack for ($($t,)*) {
#[allow(unused_parens)]
#[allow(unused_variables)]
fn pack<T: Target>(&self, writer: &mut Writer<T>) -> WriteResult<()> {
let ($($v),*) = self;
$(
writer.write($v)?;
)*
Ok(())
}
}
impl < 'a, $($t : Unpack<'a> ),*> Unpack<'a> for ($($t,)*) {
#[allow(unused_variables)]
fn unpack(reader: &mut Reader<'a>) -> ReadResult<Self> {
$(
let $v = reader.read()?;
)*
Ok(($(
$v
),*))
}
}
}
}
macro_rules! impl_for_tuple_multi {
($($args:tt,)*) => {
$( impl_for_tuple! $args; )*
}
}
impl<'a, A: Pack> Pack for &'a A {
fn pack<T: Target>(&self, writer: &mut Writer<T>) -> WriteResult<()> {
(**self).pack(writer)
}
}
impl<'a, A: Pack> Pack for &'a mut A {
fn pack<T: Target>(&self, writer: &mut Writer<T>) -> WriteResult<()> {
(**self).pack(writer)
}
}
impl Pack for bool {
fn pack<T: Target>(&self, writer: &mut Writer<T>) -> WriteResult<()> {
writer.write_u8_bits(1, if *self { 1u8 } else { 0u8 })
}
}
impl<'a> Unpack<'a> for bool {
fn unpack(reader: &mut Reader<'a>) -> ReadResult<Self> {
let me: u8 = reader.read_u8_bits(1)?;
Ok(me != 0)
}
}
impl_for_numeric_multi! {
(1, u8 ),
(2, u16),
(4, u32),
(8, u64),
(1, i8 ),
(2, i16),
(4, i32),
(8, i64),
(4, f32),
(8, f64),
}
impl_for_tuple_multi! {
(),
(a A),
(a A, b B),
(a A, b B, c C),
(a A, b B, c C, d D),
(a A, b B, c C, d D, e E),
(a A, b B, c C, d D, e E, f F),
(a A, b B, c C, d D, e E, f F, g G),
(a A, b B, c C, d D, e E, f F, g G, h H),
(a A, b B, c C, d D, e E, f F, g G, h H, i I),
(a A, b B, c C, d D, e E, f F, g G, h H, i I, j J),
}