use crate::{Bytes, Cursor, BytesRead, BytesWrite, BytesSeek};
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct BytesMut<'a> {
inner: Cursor<&'a mut [u8]>
}
impl<'a> BytesMut<'a> {
pub fn new(position: usize, inner: &'a mut [u8]) -> Self {
let mut cursor = Cursor::new(inner);
cursor.seek(position);
Self { inner: cursor }
}
}
impl BytesRead for BytesMut<'_> {
#[inline]
fn as_slice(&self) -> &[u8] {
self.inner.as_slice()
}
fn remaining(&self) -> &[u8] {
self.inner.remaining()
}
fn read(&mut self, len: usize) -> &[u8] {
self.inner.read(len)
}
fn peek(&self, len: usize) -> Option<&[u8]> {
self.inner.peek(len)
}
}
impl BytesWrite for BytesMut<'_> {
#[inline]
fn as_mut(&mut self) -> &mut [u8] {
self.inner.as_mut()
}
#[inline]
fn as_bytes(&self) -> Bytes<'_> {
self.inner.as_bytes()
}
#[inline]
fn remaining_mut(&mut self) -> &mut [u8] {
self.inner.remaining_mut()
}
#[inline]
fn write(&mut self, slice: &[u8]) {
self.inner.write(slice)
}
}
impl BytesSeek for BytesMut<'_> {
fn position(&self) -> usize {
self.inner.position()
}
fn seek(&mut self, pos: usize) {
self.inner.seek(pos)
}
}
impl<'a> From<&'a mut [u8]> for BytesMut<'a> {
fn from(s: &'a mut [u8]) -> Self {
Self::new(0, s)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::BytesRead;
#[test]
fn write() {
let mut bytes = [0u8; 100];
let mut bytes = BytesMut::from(&mut bytes[..]);
assert_eq!(bytes.len(), 100);
let to_write: Vec<u8> = (0..10).collect();
bytes.write(&to_write);
bytes.write(&to_write);
assert_eq!(bytes.remaining().len(), 100 - 20);
assert_eq!(bytes.remaining().len(), bytes.remaining_mut().len());
assert_eq!(&bytes.as_mut()[..10], to_write.as_slice());
assert_eq!(&bytes.as_bytes().peek(20).unwrap()[10..], to_write.as_slice());
bytes.write_u8(5u8);
bytes.write_u16(20u16);
assert_eq!(bytes.remaining_mut().len(), 100 - 23);
bytes.seek(99);
bytes.write_u8(5u8);
assert_eq!(bytes.remaining_mut().len(), 0);
assert_eq!(bytes.as_mut()[99], 5u8);
}
#[test]
#[should_panic]
fn write_overflow() {
let mut bytes = [0u8; 100];
let mut bytes = BytesMut::from(&mut bytes[..]);
bytes.seek(100);
bytes.write_u8(5u8);
}
}