use crate::{BytesRead, BytesWrite, BytesSeek, Bytes};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Cursor<T> {
position: usize,
inner: T
}
impl<T> Cursor<T> {
pub fn new(inner: T) -> Self {
Self {
position: 0,
inner
}
}
pub fn inner(&self) -> &T {
&self.inner
}
pub fn inner_mut(&mut self) -> &mut T {
&mut self.inner
}
pub fn into_inner(self) -> T {
self.inner
}
}
impl<T> BytesRead for Cursor<T>
where T: AsRef<[u8]> {
#[inline]
fn as_slice(&self) -> &[u8] {
self.inner.as_ref()
}
#[inline]
fn remaining(&self) -> &[u8] {
&self.as_slice()[self.position..]
}
fn read(&mut self, len: usize) -> &[u8] {
let slice = &self.inner.as_ref()[self.position..][..len];
self.position += len;
slice
}
fn peek(&self, len: usize) -> Option<&[u8]> {
self.remaining().get(..len)
}
}
impl<'a> BytesSeek for Cursor<&'a [u8]> {
fn position(&self) -> usize {
self.position
}
fn seek(&mut self, pos: usize) {
let len = self.inner.len();
assert!(self.position + len > pos);
self.position = pos;
}
}
impl<'a> BytesWrite for Cursor<&'a mut [u8]> {
fn as_mut(&mut self) -> &mut [u8] {
self.inner
}
fn as_bytes(&self) -> Bytes<'_> {
Bytes::new(0, &*self.inner)
}
fn remaining_mut(&mut self) -> &mut [u8] {
&mut self.inner[self.position..]
}
fn write(&mut self, slice: &[u8]) {
self.remaining_mut()[..slice.len()].copy_from_slice(slice);
self.position += slice.len();
}
}
impl<'a> BytesSeek for Cursor<&'a mut [u8]> {
fn position(&self) -> usize {
self.position
}
fn seek(&mut self, pos: usize) {
let len = self.inner.len();
assert!(self.position + len > pos);
self.position = pos;
}
}
impl BytesWrite for Cursor<Vec<u8>> {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.inner
}
fn as_bytes(&self) -> Bytes<'_> {
Bytes::new(0, &self.inner)
}
fn remaining_mut(&mut self) -> &mut [u8] {
&mut self.inner[self.position..]
}
fn write(&mut self, slice: &[u8]) {
if slice.len() <= self.remaining_mut().len() {
self.remaining_mut()[..slice.len()].copy_from_slice(slice);
self.position += slice.len();
return;
}
let rem = self.remaining_mut().len();
if rem > 0 {
self.remaining_mut().copy_from_slice(&slice[..rem]);
}
self.inner.extend_from_slice(&slice[rem..]);
self.position += slice.len();
}
}
impl BytesSeek for Cursor<Vec<u8>> {
fn position(&self) -> usize {
self.position
}
fn seek(&mut self, pos: usize) {
self.position = pos;
let n_len = self.position + 1;
if self.inner.len() < n_len {
self.inner.resize(n_len, 0u8);
}
}
}
impl BytesWrite for Cursor<&mut Vec<u8>> {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.inner
}
fn as_bytes(&self) -> Bytes<'_> {
Bytes::new(0, &self.inner)
}
fn remaining_mut(&mut self) -> &mut [u8] {
&mut self.inner[self.position..]
}
fn write(&mut self, slice: &[u8]) {
if slice.len() <= self.remaining_mut().len() {
self.remaining_mut()[..slice.len()].copy_from_slice(slice);
self.position += slice.len();
return;
}
let rem = self.remaining_mut().len();
if rem > 0 {
self.remaining_mut().copy_from_slice(&slice[..rem]);
}
self.inner.extend_from_slice(&slice[rem..]);
self.position += slice.len();
}
}
impl BytesSeek for Cursor<&mut Vec<u8>> {
fn position(&self) -> usize {
self.position
}
fn seek(&mut self, pos: usize) {
self.position = pos;
let n_len = self.position + 1;
if self.inner.len() < n_len {
self.inner.resize(n_len, 0u8);
}
}
}