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
pub use std::io::{Read, Write};
pub trait Packable {
type Error;
fn packed_len(&self) -> usize;
fn pack<W: Write>(&self, writer: &mut W) -> Result<(), Self::Error>;
fn pack_new(&self) -> Result<Vec<u8>, Self::Error> {
let mut bytes = Vec::with_capacity(self.packed_len());
self.pack(&mut bytes)?;
Ok(bytes)
}
fn unpack<R: Read + ?Sized>(reader: &mut R) -> Result<Self, Self::Error>
where
Self: Sized;
}
macro_rules! impl_packable_for_num {
($ty:ident) => {
impl Packable for $ty {
type Error = std::io::Error;
fn packed_len(&self) -> usize {
std::mem::size_of_val(&self.to_le_bytes())
}
fn pack<W: Write>(&self, writer: &mut W) -> Result<(), Self::Error> {
writer.write_all(&self.to_le_bytes())?;
Ok(())
}
fn unpack<R: Read + ?Sized>(reader: &mut R) -> Result<Self, Self::Error> {
let mut bytes = [0; $ty::MIN.to_le_bytes().len()];
reader.read_exact(&mut bytes)?;
Ok($ty::from_le_bytes(bytes))
}
}
};
}
impl_packable_for_num!(i8);
impl_packable_for_num!(u8);
impl_packable_for_num!(i16);
impl_packable_for_num!(u16);
impl_packable_for_num!(i32);
impl_packable_for_num!(u32);
impl_packable_for_num!(i64);
impl_packable_for_num!(u64);
impl_packable_for_num!(i128);
impl_packable_for_num!(u128);