use bytes::{Buf, Bytes};
use codec::{Decode, Input};
pub struct BytesCursor {
bytes: Bytes,
position: usize,
}
impl BytesCursor {
pub fn is_empty(&self) -> bool {
self.position == self.bytes.len()
}
pub fn infallible_remaining_len(&self) -> usize {
self.bytes.len() - self.position
}
fn align(&mut self) {
self.bytes.advance(self.position);
self.position = 0;
}
pub fn remaining(&mut self) -> &Bytes {
self.align();
&self.bytes
}
pub fn read_bytes(&mut self, len: usize) -> Result<Bytes, codec::Error> {
self.align();
if len > self.bytes.len() {
return Err("Not enough data".into())
}
Ok(self.bytes.split_to(len))
}
pub fn decode_all<T: Decode>(&mut self) -> Result<T, codec::Error> {
let value = T::decode(self)?;
if !self.is_empty() {
return Err("Extraneous bytes".into())
}
Ok(value)
}
}
impl Input for BytesCursor {
fn remaining_len(&mut self) -> Result<Option<usize>, codec::Error> {
Ok(Some(self.infallible_remaining_len()))
}
fn read(&mut self, into: &mut [u8]) -> Result<(), codec::Error> {
if into.len() > self.infallible_remaining_len() {
return Err("Not enough data".into())
}
into.copy_from_slice(&self.bytes[self.position..self.position + into.len()]);
self.position += into.len();
Ok(())
}
fn scale_internal_decode_bytes(&mut self) -> Result<Bytes, codec::Error> {
let length = <codec::Compact<u32>>::decode(self)?.0 as usize;
self.read_bytes(length)
}
}
impl From<Bytes> for BytesCursor {
fn from(bytes: Bytes) -> Self {
Self { bytes, position: 0 }
}
}
impl From<Vec<u8>> for BytesCursor {
fn from(vec: Vec<u8>) -> Self {
Bytes::from(vec).into()
}
}
unsafe impl castaway::LifetimeFree for BytesCursor {}