1 | use std::io::{Read, Result, Write}; |
2 | |
3 | use crate::Endian; |
4 | |
5 | macro_rules! decl_read_method { |
6 | ($type:ty, $method:ident) => { |
7 | #[doc = concat!("Read a `" , stringify!($type), "`." )] |
8 | fn $method(&mut self, endian: Endian) -> Result<$type>; |
9 | }; |
10 | } |
11 | |
12 | /// A trait for reading bytes. |
13 | /// |
14 | /// This is implemented for all types that implement [`Read`]. |
15 | pub trait ReadBytes { |
16 | decl_read_method!(u8, read_u8); |
17 | decl_read_method!(u16, read_u16); |
18 | decl_read_method!(u32, read_u32); |
19 | decl_read_method!(u64, read_u64); |
20 | decl_read_method!(u128, read_u128); |
21 | |
22 | decl_read_method!(i8, read_i8); |
23 | decl_read_method!(i16, read_i16); |
24 | decl_read_method!(i32, read_i32); |
25 | decl_read_method!(i64, read_i64); |
26 | decl_read_method!(i128, read_i128); |
27 | |
28 | decl_read_method!(f32, read_f32); |
29 | decl_read_method!(f64, read_f64); |
30 | } |
31 | |
32 | macro_rules! impl_read_method { |
33 | ($type:ty, $method:ident, $size:literal) => { |
34 | #[inline] |
35 | fn $method(&mut self, endian: Endian) -> Result<$type> { |
36 | let mut buf = [0; $size]; |
37 | self.read_exact(&mut buf)?; |
38 | Ok(endian.$method(&buf)) |
39 | } |
40 | }; |
41 | } |
42 | |
43 | impl<R: Read> ReadBytes for R { |
44 | impl_read_method!(u8, read_u8, 1); |
45 | impl_read_method!(u16, read_u16, 2); |
46 | impl_read_method!(u32, read_u32, 4); |
47 | impl_read_method!(u64, read_u64, 8); |
48 | impl_read_method!(u128, read_u128, 16); |
49 | |
50 | impl_read_method!(i8, read_i8, 1); |
51 | impl_read_method!(i16, read_i16, 2); |
52 | impl_read_method!(i32, read_i32, 4); |
53 | impl_read_method!(i64, read_i64, 8); |
54 | impl_read_method!(i128, read_i128, 16); |
55 | |
56 | impl_read_method!(f32, read_f32, 4); |
57 | impl_read_method!(f64, read_f64, 8); |
58 | } |
59 | |
60 | macro_rules! decl_write_method { |
61 | ($type:ty, $method:ident) => { |
62 | #[doc = concat!("Write a `" , stringify!($type), "`." )] |
63 | fn $method(&mut self, endian: Endian, n: $type) -> Result<()>; |
64 | }; |
65 | } |
66 | |
67 | /// A trait for writing bytes. |
68 | /// |
69 | /// This is implemented for all types that implement [`Write`]. |
70 | pub trait WriteBytes { |
71 | decl_write_method!(u8, write_u8); |
72 | decl_write_method!(u16, write_u16); |
73 | decl_write_method!(u32, write_u32); |
74 | decl_write_method!(u64, write_u64); |
75 | decl_write_method!(u128, write_u128); |
76 | |
77 | decl_write_method!(i8, write_i8); |
78 | decl_write_method!(i16, write_i16); |
79 | decl_write_method!(i32, write_i32); |
80 | decl_write_method!(i64, write_i64); |
81 | decl_write_method!(i128, write_i128); |
82 | |
83 | decl_write_method!(f32, write_f32); |
84 | decl_write_method!(f64, write_f64); |
85 | } |
86 | |
87 | macro_rules! impl_write_method { |
88 | ($type:ty, $method:ident, $size:literal) => { |
89 | #[inline] |
90 | fn $method(&mut self, endian: Endian, n: $type) -> Result<()> { |
91 | let mut buf = [0; $size]; |
92 | endian.$method(&mut buf, n); |
93 | self.write_all(&buf) |
94 | } |
95 | }; |
96 | } |
97 | |
98 | impl<W: Write> WriteBytes for W { |
99 | impl_write_method!(u8, write_u8, 1); |
100 | impl_write_method!(u16, write_u16, 2); |
101 | impl_write_method!(u32, write_u32, 4); |
102 | impl_write_method!(u64, write_u64, 8); |
103 | impl_write_method!(u128, write_u128, 16); |
104 | |
105 | impl_write_method!(i8, write_i8, 1); |
106 | impl_write_method!(i16, write_i16, 2); |
107 | impl_write_method!(i32, write_i32, 4); |
108 | impl_write_method!(i64, write_i64, 8); |
109 | impl_write_method!(i128, write_i128, 16); |
110 | |
111 | impl_write_method!(f32, write_f32, 4); |
112 | impl_write_method!(f64, write_f64, 8); |
113 | } |
114 | |