1use crate::CodecError;
4
5pub trait DecodeSource {
7 fn read_exact(&mut self, out: &mut [u8]) -> Result<(), CodecError>;
9
10 fn remaining_len(&self) -> Option<usize> {
16 None
17 }
18}
19
20pub trait CanonicalDecode: Sized {
22 fn decode<R: DecodeSource + ?Sized>(reader: &mut R) -> Result<Self, CodecError>;
24}
25
26#[derive(Debug, Clone)]
28pub struct SliceReader<'a> {
29 input: &'a [u8],
30 offset: usize,
31}
32
33impl<'a> SliceReader<'a> {
34 pub const fn new(input: &'a [u8]) -> Self {
36 Self { input, offset: 0 }
37 }
38
39 pub const fn remaining(&self) -> usize {
41 self.input.len() - self.offset
42 }
43
44 pub const fn is_empty(&self) -> bool {
46 self.remaining() == 0
47 }
48}
49
50impl DecodeSource for SliceReader<'_> {
51 fn read_exact(&mut self, out: &mut [u8]) -> Result<(), CodecError> {
52 let end = self
53 .offset
54 .checked_add(out.len())
55 .ok_or_else(|| CodecError::length_overflow("read offset overflow"))?;
56 let bytes = self
57 .input
58 .get(self.offset..end)
59 .ok_or_else(CodecError::unexpected_eof)?;
60 out.copy_from_slice(bytes);
61 self.offset = end;
62 Ok(())
63 }
64
65 fn remaining_len(&self) -> Option<usize> {
66 Some(self.remaining())
67 }
68}