simple_bytes/
bytes.rs

1
2use crate::{BytesRead, ReadError, BytesReadRef, BytesSeek, SeekError, Cursor};
3
4use std::io;
5
6/// A slice wrapper that implements BytesRead.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub struct Bytes<'a> {
9	inner: Cursor<&'a [u8]>
10}
11
12impl<'a> Bytes<'a> {
13	/// You should probably use:
14	///
15	/// ```
16	/// # use simple_bytes::Bytes;
17	/// # let slice = &[1u8, 2u8][..];
18	/// let bytes: Bytes = slice.into();
19	/// // or
20	/// let bytes = Bytes::from(slice);
21	/// ```
22	///
23	pub fn new(position: usize, inner: &'a [u8]) -> Self {
24		let mut cursor = Cursor::new(inner);
25		cursor.seek(position);
26		Self { inner: cursor }
27	}
28
29	/// Returns the inner slice with the original reference.
30	pub fn inner(&self) -> &'a [u8] {
31		self.as_slice_ref()
32	}
33}
34
35impl BytesRead for Bytes<'_> {
36	// returns the full slice
37	#[inline]
38	fn as_slice(&self) -> &[u8] {
39		self.inner.as_slice()
40	}
41
42	#[inline]
43	fn remaining(&self) -> &[u8] {
44		self.inner.remaining()
45	}
46
47	#[inline]
48	fn try_read(&mut self, len: usize) -> Result<&[u8], ReadError> {
49		self.inner.try_read(len)
50	}
51
52	#[inline]
53	fn peek(&self, len: usize) -> Option<&[u8]> {
54		self.inner.peek(len)
55	}
56}
57
58impl io::Read for Bytes<'_> {
59	fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
60		io::Read::read(&mut self.inner, buf)
61	}
62}
63
64impl<'a> BytesReadRef<'a> for Bytes<'a> {
65
66	// returns the full slice
67	#[inline]
68	fn as_slice_ref(&self) -> &'a [u8] {
69		*self.inner.inner()
70	}
71
72	#[inline]
73	fn remaining_ref(&self) -> &'a [u8] {
74		&self.as_slice_ref()[self.position()..]
75	}
76
77	#[inline]
78	fn try_read_ref(&mut self, len: usize) -> Result<&'a [u8], ReadError> {
79		let slice = &self.as_slice_ref()[self.position()..].get(..len)
80			.ok_or(ReadError)?;
81		// the previous line did not panic
82		// so let's increase our position
83		self.seek(self.position() + len);
84
85		Ok(slice)
86	}
87
88	#[inline]
89	fn peek_ref(&self, len: usize) -> Option<&'a [u8]> {
90		self.remaining_ref().get(..len)
91	}
92
93}
94
95impl BytesSeek for Bytes<'_> {
96	/// Returns the internal position.
97	fn position(&self) -> usize {
98		self.inner.position()
99	}
100
101	/// Sets the internal position.
102	/// 
103	/// ## Fails
104	/// If the position exceeds the slice.
105	fn try_seek(&mut self, pos: usize) -> Result<(), SeekError> {
106		self.inner.try_seek(pos)
107	}
108}
109
110impl io::Seek for Bytes<'_> {
111	fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
112		io::Seek::seek(&mut self.inner, pos)
113	}
114}
115
116impl<'a> From<&'a [u8]> for Bytes<'a> {
117	fn from(s: &'a [u8]) -> Self {
118		Self::new(0, s)
119	}
120}
121
122#[cfg(test)]
123mod tests {
124
125	use super::*;
126
127	#[test]
128	fn read() {
129
130		let bytes: Vec<u8> = (0..=255).collect();
131		let mut bytes = Bytes::from(bytes.as_slice());
132		assert_eq!(bytes.as_slice(), bytes.as_slice());
133		assert_eq!(bytes.len(), 256);
134		assert_eq!(bytes.remaining().len(), 256);
135
136		let to_read: Vec<u8> = (0..10).collect();
137		assert_eq!(to_read.as_slice(), bytes.read(10));
138		assert_eq!(bytes.remaining().len(), 256 - 10);
139
140		assert_eq!(10u8, bytes.read_u8());
141
142		// peek
143		let to_peek: Vec<u8> = (11..=20).collect();
144		assert_eq!(to_peek.as_slice(), bytes.peek(10).unwrap());
145
146		bytes.seek(255);
147		assert_eq!(255u8, bytes.read_u8());
148
149		assert_eq!(bytes.position(), 256);
150		bytes.seek(256);
151	}
152
153	#[test]
154	fn read_le() {
155
156		let b = u16::MAX - 20;
157		println!("be: {:?}", b.to_be_bytes());
158		let bytes = b.to_le_bytes();
159		println!("le: {:?}", bytes);
160		let mut bytes = Bytes::from(&bytes[..]);
161		assert_ne!(bytes.read_u16(), b);
162		bytes.seek(0);
163		println!("buffer: {:?}", bytes.as_slice());
164		assert_eq!(bytes.read_le_u16(), b);
165
166	}
167
168	#[test]
169	fn test_empty() {
170		let mut bytes = Bytes::from(&[][..]);
171		assert_eq!(bytes.as_slice(), &[]);
172		assert_eq!(bytes.len(), 0);
173		bytes.seek(0);
174	}
175
176	#[test]
177	#[should_panic]
178	fn test_seek_empty() {
179		let mut bytes = Bytes::from(&[][..]);
180		bytes.seek(1);
181	}
182
183	#[test]
184	#[should_panic]
185	fn read_out_of_bound() {
186
187		let bytes = [0u8; 100];
188		let mut bytes = Bytes::from(&bytes[..]);
189
190		bytes.seek(100);
191
192		let _ = bytes.read_u8();
193	}
194
195	#[test]
196	#[should_panic]
197	fn seek_out_of_bound() {
198
199		let bytes = [0u8; 100];
200		let mut bytes = Bytes::from(&bytes[..]);
201
202		bytes.seek(101);
203	}
204
205}