use crate::CodecError;
pub trait DecodeSource {
fn read_exact(&mut self, out: &mut [u8]) -> Result<(), CodecError>;
fn remaining_len(&self) -> Option<usize> {
None
}
}
pub trait CanonicalDecode: Sized {
fn decode<R: DecodeSource + ?Sized>(reader: &mut R) -> Result<Self, CodecError>;
}
#[derive(Debug, Clone)]
pub struct SliceReader<'a> {
input: &'a [u8],
offset: usize,
}
impl<'a> SliceReader<'a> {
pub const fn new(input: &'a [u8]) -> Self {
Self { input, offset: 0 }
}
pub const fn remaining(&self) -> usize {
self.input.len() - self.offset
}
pub const fn is_empty(&self) -> bool {
self.remaining() == 0
}
}
impl DecodeSource for SliceReader<'_> {
fn read_exact(&mut self, out: &mut [u8]) -> Result<(), CodecError> {
let end = self
.offset
.checked_add(out.len())
.ok_or_else(|| CodecError::length_overflow("read offset overflow"))?;
let bytes = self
.input
.get(self.offset..end)
.ok_or_else(CodecError::unexpected_eof)?;
out.copy_from_slice(bytes);
self.offset = end;
Ok(())
}
fn remaining_len(&self) -> Option<usize> {
Some(self.remaining())
}
}