1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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),
}