simple_bytes/
bytes_read.rs

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		///
34		/// ## Panics
35		/// If there aren't enough bytes left.
36		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		///
72		/// ## Panics
73		/// If there aren't enough bytes left.
74		fn $name(&mut self) -> $type {
75			self.$try_name().expect(concat!("failed to read ", $type_str))
76		}
77	}
78}
79
80/// Get's returned when there is not enough space to read everything.
81/// If this get's returned nothing was read.
82#[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
93/// Read bytes or numbers.
94pub trait BytesRead {
95	/// Returns the entire slice.
96	fn as_slice(&self) -> &[u8];
97
98	/// Returns the length of the entire slice.
99	#[inline]
100	fn len(&self) -> usize {
101		self.as_slice().len()
102	}
103
104	/// Returns all remaining bytes.
105	fn remaining(&self) -> &[u8];
106
107	/// Try to read a given length of bytes.
108	/// 
109	/// ## Failes
110	/// If len exceeds `self.remaining().len()`.
111	fn try_read(&mut self, len: usize) -> Result<&[u8], ReadError>;
112
113	/// Reads a given length of bytes.
114	/// 
115	/// ## Panics
116	/// If len exceeds `self.remaining().len()`.
117	#[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	/// Tries to read a given length without updating
153	/// the internal position. Returns `None` if there are not enought
154	/// bytes remaining.
155	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
180/// Read bytes while keeping the original reference.
181/// ```
182/// use simple_bytes::{Bytes, BytesRead, BytesReadRef};
183///
184/// let mut bytes = Bytes::from("hey".as_ref());
185/// let h = bytes.read_u8();
186/// let ey: &'static [u8] = bytes.remaining_ref();
187/// ```
188pub trait BytesReadRef<'a>: BytesRead {
189	/// Returns the entire slice.
190	fn as_slice_ref(&self) -> &'a [u8];
191
192	/// Returns all remaining bytes.
193	fn remaining_ref(&self) -> &'a [u8];
194
195	/// Try to read a given length of bytes.
196	/// 
197	/// ## Failes
198	/// If len exceeds `self.remaining().len()`.
199	fn try_read_ref(&mut self, len: usize) -> Result<&'a [u8], ReadError>;
200
201	/// Reads a given length of bytes.
202	/// 
203	/// ## Panics
204	/// If len exceeds `self.remaining().len()`.
205	#[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	/// Tries to read a given length without updating
211	/// the internal position. Returns `None` if there are not enought
212	/// bytes remaining.
213	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}