simple_bytes/
bytes_mut.rs

1
2use crate::{
3	Bytes, Cursor,
4	BytesRead, ReadError,
5	BytesWrite, WriteError,
6	BytesSeek, SeekError
7};
8
9use std::io;
10
11/// A mutable slice wrapper that implements BytesWrite
12#[derive(Debug, PartialEq, Eq, Hash)]
13pub struct BytesMut<'a> {
14	inner: Cursor<&'a mut [u8]>
15}
16
17impl<'a> BytesMut<'a> {
18	/// You should probably use:
19	///
20	/// ```
21	/// # use simple_bytes::BytesMut;
22	/// # let slice = &mut [1u8, 2u8][..];
23	/// let bytes: BytesMut = slice.into();
24	/// // or
25	/// let bytes = BytesMut::from(slice);
26	/// ```
27	///
28	pub fn new(position: usize, inner: &'a mut [u8]) -> Self {
29		let mut cursor = Cursor::new(inner);
30		cursor.seek(position);
31		Self { inner: cursor }
32	}
33}
34
35impl BytesRead for BytesMut<'_> {
36	#[inline]
37	fn as_slice(&self) -> &[u8] {
38		self.inner.as_slice()
39	}
40
41	fn remaining(&self) -> &[u8] {
42		self.inner.remaining()
43	}
44
45	fn try_read(&mut self, len: usize) -> Result<&[u8], ReadError> {
46		self.inner.try_read(len)
47	}
48
49	fn peek(&self, len: usize) -> Option<&[u8]> {
50		self.inner.peek(len)
51	}
52}
53
54impl io::Read for BytesMut<'_> {
55	fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
56		io::Read::read(&mut self.inner, buf)
57	}
58}
59
60impl BytesWrite for BytesMut<'_> {
61	#[inline]
62	fn as_mut(&mut self) -> &mut [u8] {
63		self.inner.as_mut()
64	}
65
66	#[inline]
67	fn as_bytes(&self) -> Bytes<'_> {
68		self.inner.as_bytes()
69	}
70
71	#[inline]
72	fn remaining_mut(&mut self) -> &mut [u8] {
73		self.inner.remaining_mut()
74	}
75
76	#[inline]
77	fn try_write(&mut self, slice: impl AsRef<[u8]>) -> Result<(), WriteError> {
78		self.inner.try_write(slice)
79	}
80}
81
82impl io::Write for BytesMut<'_> {
83	fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
84		io::Write::write(&mut self.inner, buf)
85	}
86
87	fn flush(&mut self) -> io::Result<()> {
88		Ok(())
89	}
90}
91
92impl BytesSeek for BytesMut<'_> {
93	/// Returns the internal position.
94	fn position(&self) -> usize {
95		self.inner.position()
96	}
97
98	/// Sets the internal position.
99	/// 
100	/// ## Fails
101	/// If the position exceeds the slice.
102	fn try_seek(&mut self, pos: usize) -> Result<(), SeekError> {
103		self.inner.try_seek(pos)
104	}
105}
106
107impl io::Seek for BytesMut<'_> {
108	fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
109		io::Seek::seek(&mut self.inner, pos)
110	}
111}
112
113impl<'a> From<&'a mut [u8]> for BytesMut<'a> {
114	fn from(s: &'a mut [u8]) -> Self {
115		Self::new(0, s)
116	}
117}
118
119
120#[cfg(test)]
121mod tests {
122
123	use super::*;
124	use crate::BytesRead;
125
126	#[test]
127	fn write() {
128
129		let mut bytes = [0u8; 100];
130		let mut bytes = BytesMut::from(&mut bytes[..]);
131		assert_eq!(bytes.len(), 100);
132
133		let to_write: Vec<u8> = (0..10).collect();
134		bytes.write(&to_write);
135		bytes.write(&to_write);
136
137		assert_eq!(bytes.remaining().len(), 100 - 20);
138		assert_eq!(bytes.remaining().len(), bytes.remaining_mut().len());
139
140		assert_eq!(&bytes.as_mut()[..10], to_write.as_slice());
141		assert_eq!(&bytes.as_bytes().peek(20).unwrap()[10..], to_write.as_slice());
142
143		bytes.write_u8(5u8);
144		bytes.write_u16(20u16);
145
146		assert_eq!(bytes.remaining_mut().len(), 100 - 23);
147
148		// seek
149		bytes.seek(99);
150		// should now write to the 99 byte // this is the last byte
151		bytes.write_u8(5u8);
152		assert_eq!(bytes.remaining_mut().len(), 0);
153		assert_eq!(bytes.as_mut()[99], 5u8);
154
155	}
156
157	#[test]
158	fn write_le() {
159		let b = u16::MAX - 20;
160		let le = b.to_le_bytes();
161		let mut bytes = [0u8; 2];
162		let mut bytes = BytesMut::from(bytes.as_mut());
163		bytes.write_le_u16(b);
164		assert_eq!(bytes.as_slice(), le);
165	}
166
167	#[test]
168	fn test_empty() {
169		let mut bytes = BytesMut::from(&mut [][..]);
170		assert_eq!(bytes.as_slice(), &[]);
171		assert_eq!(bytes.len(), 0);
172		bytes.seek(0);
173	}
174
175	#[test]
176	#[should_panic]
177	fn write_overflow() {
178
179		let mut bytes = [0u8; 100];
180		let mut bytes = BytesMut::from(&mut bytes[..]);
181
182		// seek
183		bytes.seek(100);
184
185		bytes.write_u8(5u8);
186	}
187
188}