mod decoder;
mod impl_tuples;
mod impls;
pub mod read;
use crate::{config::Config, error::Error, utils::Sealed};
pub use self::decoder::DecoderImpl;
pub use self::read::{Reader, SliceReader, SliceReaderBorrow};
#[cfg(feature = "std")]
pub use self::read::{BufferedIoReader, IoReader, StdReader};
pub trait Decode<Context = ()>: Sized {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, Error>;
}
pub trait BorrowDecode<'de, Context = ()>: Sized {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, Error>;
}
pub trait Decoder: Sealed {
type R: Reader;
type C: Config;
type Context;
fn reader(&mut self) -> &mut Self::R;
fn config(&self) -> &Self::C;
fn context(&mut self) -> &mut Self::Context;
#[inline]
fn claim_bytes_read(&mut self, _n: usize) -> Result<(), Error> {
Ok(())
}
#[inline]
fn unclaim_bytes_read(&mut self, _n: usize) {
}
#[inline]
fn claim_container_read<T>(&mut self, len: usize) -> Result<(), Error> {
let size = core::mem::size_of::<T>().saturating_mul(len);
self.claim_bytes_read(size)
}
}
pub trait BorrowDecoder<'de>: Decoder {
type BR: BorrowReader<'de>;
fn borrow_reader(&mut self) -> &mut Self::BR;
}
pub trait BorrowReader<'de>: Reader {
fn take_bytes(&mut self, length: usize) -> Result<&'de [u8], Error>;
#[inline]
fn peek_read(&self, _n: usize) -> Option<&'de [u8]> {
None
}
#[inline]
fn consume(&mut self, _n: usize) {
}
}
impl<T> Decoder for &mut T
where
T: Decoder,
{
type R = T::R;
type C = T::C;
type Context = T::Context;
fn reader(&mut self) -> &mut Self::R {
T::reader(self)
}
fn config(&self) -> &Self::C {
T::config(self)
}
fn context(&mut self) -> &mut Self::Context {
T::context(self)
}
fn claim_bytes_read(&mut self, n: usize) -> Result<(), Error> {
T::claim_bytes_read(self, n)
}
fn unclaim_bytes_read(&mut self, n: usize) {
T::unclaim_bytes_read(self, n)
}
}
impl<'de, T> BorrowDecoder<'de> for &mut T
where
T: BorrowDecoder<'de>,
{
type BR = T::BR;
fn borrow_reader(&mut self) -> &mut Self::BR {
T::borrow_reader(self)
}
}
#[inline]
#[allow(dead_code)]
pub(crate) fn decode_option_variant<D: Decoder<Context = ()>>(
decoder: &mut D,
) -> Result<Option<()>, Error> {
let variant = u8::decode(decoder)?;
match variant {
0 => Ok(None),
1 => Ok(Some(())),
_v => Err(Error::InvalidData {
message: "Invalid Option variant",
}),
}
}
#[inline]
#[allow(dead_code)]
pub(crate) fn decode_slice_len<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<usize, Error> {
u64::decode(decoder).map(|len| len as usize)
}
#[macro_export]
macro_rules! impl_borrow_decode {
($ty:ty) => {
impl<'de> $crate::de::BorrowDecode<'de> for $ty {
fn borrow_decode<D: $crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, $crate::error::Error> {
<$ty as $crate::de::Decode>::decode(decoder)
}
}
};
($ty:ty, $ctx:ty) => {
impl<'de> $crate::de::BorrowDecode<'de, $ctx> for $ty {
fn borrow_decode<D: $crate::de::BorrowDecoder<'de, Context = $ctx>>(
decoder: &mut D,
) -> Result<Self, $crate::error::Error> {
<$ty as $crate::de::Decode<$ctx>>::decode(decoder)
}
}
};
}