1
2use std::fmt;
3
4macro_rules! read_fn {
5 ($name:ident, $try_name:ident, $type:ident, $num:expr) => (
6 read_fn!(
7 $name, $try_name,
8 $type, $num, stringify!($type), stringify!($num)
9 );
10 );
11 ($name:ident, $try_name:ident, $type:ident, $num:expr,
12 $type_str:expr, $num_str:expr) => {
13 #[inline]
14 #[doc = "Try to read "]
15 #[doc = $num_str]
16 #[doc = " bytes in big-endian converting them into an `"]
17 #[doc = $type_str]
18 #[doc = "`."]
19 fn $try_name(&mut self) -> Result<$type, ReadError> {
20 self.try_read($num)?
21 .try_into()
22 .map($type::from_be_bytes)
23 .map_err(|_| ReadError)
24 }
25
26 #[inline]
27 #[track_caller]
28 #[doc = "Reads "]
29 #[doc = $num_str]
30 #[doc = " bytes in big-endian converting them into an `"]
31 #[doc = $type_str]
32 #[doc = "`."]
33 fn $name(&mut self) -> $type {
37 self.$try_name().expect(concat!("failed to read ", $type_str))
38 }
39 }
40}
41
42macro_rules! read_le_fn {
43 ($name:ident, $try_name:ident, $type:ident, $num:expr) => (
44 read_le_fn!(
45 $name, $try_name,
46 $type, $num, stringify!($type), stringify!($num)
47 );
48 );
49 ($name:ident, $try_name:ident, $type:ident, $num:expr,
50 $type_str:expr, $num_str:expr) => {
51 #[inline]
52 #[doc = "Try to read "]
53 #[doc = $num_str]
54 #[doc = " bytes in little-endian converting them into an `"]
55 #[doc = $type_str]
56 #[doc = "`."]
57 fn $try_name(&mut self) -> Result<$type, ReadError> {
58 self.try_read($num)?
59 .try_into()
60 .map($type::from_le_bytes)
61 .map_err(|_| ReadError)
62 }
63
64 #[inline]
65 #[track_caller]
66 #[doc = "Reads "]
67 #[doc = $num_str]
68 #[doc = " bytes in little-endian converting them into an `"]
69 #[doc = $type_str]
70 #[doc = "`."]
71 fn $name(&mut self) -> $type {
75 self.$try_name().expect(concat!("failed to read ", $type_str))
76 }
77 }
78}
79
80#[derive(Debug, Clone, Copy, PartialEq, Eq)]
83pub struct ReadError;
84
85impl fmt::Display for ReadError {
86 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87 fmt::Debug::fmt(self, f)
88 }
89}
90
91impl std::error::Error for ReadError {}
92
93pub trait BytesRead {
95 fn as_slice(&self) -> &[u8];
97
98 #[inline]
100 fn len(&self) -> usize {
101 self.as_slice().len()
102 }
103
104 fn remaining(&self) -> &[u8];
106
107 fn try_read(&mut self, len: usize) -> Result<&[u8], ReadError>;
112
113 #[track_caller]
118 fn read(&mut self, len: usize) -> &[u8] {
119 self.try_read(len).expect("failed to read")
120 }
121
122 read_fn!(read_u8, try_read_u8, u8, 1);
123 read_fn!(read_u16, try_read_u16, u16, 2);
124 read_fn!(read_u32, try_read_u32, u32, 4);
125 read_fn!(read_u64, try_read_u64, u64, 8);
126 read_fn!(read_u128, try_read_u128, u128, 16);
127
128 read_fn!(read_i8, try_read_i8, i8, 1);
129 read_fn!(read_i16, try_read_i16, i16, 2);
130 read_fn!(read_i32, try_read_i32, i32, 4);
131 read_fn!(read_i64, try_read_i64, i64, 8);
132 read_fn!(read_i128, try_read_i128, i128, 16);
133
134 read_fn!(read_f32, try_read_f32, f32, 4);
135 read_fn!(read_f64, try_read_f64, f64, 8);
136
137 read_le_fn!(read_le_u8, try_read_le_u8, u8, 1);
138 read_le_fn!(read_le_u16, try_read_le_u16, u16, 2);
139 read_le_fn!(read_le_u32, try_read_le_u32, u32, 4);
140 read_le_fn!(read_le_u64, try_read_le_u64, u64, 8);
141 read_le_fn!(read_le_u128, try_read_le_u128, u128, 16);
142
143 read_le_fn!(read_le_i8, try_read_le_i8, i8, 1);
144 read_le_fn!(read_le_i16, try_read_le_i16, i16, 2);
145 read_le_fn!(read_le_i32, try_read_le_i32, i32, 4);
146 read_le_fn!(read_le_i64, try_read_le_i64, i64, 8);
147 read_le_fn!(read_le_i128, try_read_le_i128, i128, 16);
148
149 read_le_fn!(read_le_f32, try_read_le_f32, f32, 4);
150 read_le_fn!(read_le_f64, try_read_le_f64, f64, 8);
151
152 fn peek(&self, len: usize) -> Option<&[u8]>;
156}
157
158impl<R: BytesRead> BytesRead for &mut R {
159 #[inline]
160 fn as_slice(&self) -> &[u8] {
161 (**self).as_slice()
162 }
163
164 #[inline]
165 fn remaining(&self) -> &[u8] {
166 (**self).remaining()
167 }
168
169 #[inline]
170 fn try_read(&mut self, len: usize) -> Result<&[u8], ReadError> {
171 (**self).try_read(len)
172 }
173
174 #[inline]
175 fn peek(&self, len: usize) -> Option<&[u8]> {
176 (**self).peek(len)
177 }
178}
179
180pub trait BytesReadRef<'a>: BytesRead {
189 fn as_slice_ref(&self) -> &'a [u8];
191
192 fn remaining_ref(&self) -> &'a [u8];
194
195 fn try_read_ref(&mut self, len: usize) -> Result<&'a [u8], ReadError>;
200
201 #[track_caller]
206 fn read_ref(&mut self, len: usize) -> &'a [u8] {
207 self.try_read_ref(len).expect("failed to read")
208 }
209
210 fn peek_ref(&self, len: usize) -> Option<&'a [u8]>;
214}
215
216impl<'a, R: BytesReadRef<'a>> BytesReadRef<'a> for &mut R {
217 #[inline]
218 fn as_slice_ref(&self) -> &'a [u8] {
219 (**self).as_slice_ref()
220 }
221
222 #[inline]
223 fn remaining_ref(&self) -> &'a [u8] {
224 (**self).remaining_ref()
225 }
226
227 #[inline]
228 fn try_read_ref(&mut self, len: usize) -> Result<&'a [u8], ReadError> {
229 (**self).try_read_ref(len)
230 }
231
232 #[inline]
233 fn peek_ref(&self, len: usize) -> Option<&'a [u8]> {
234 (**self).peek_ref(len)
235 }
236}