mod decoder;
mod impl_core;
mod impl_tuples;
mod impls;
use self::{
decoder::WithContext,
read::{BorrowReader, Reader},
};
use crate::{
config::{Config, InternalLimitConfig},
error::DecodeError,
utils::Sealed,
};
pub mod read;
pub use self::decoder::DecoderImpl;
pub trait Decode<Context>: Sized {
fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError>;
}
pub trait BorrowDecode<'de, Context>: Sized {
fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
decoder: &mut D,
) -> Result<Self, DecodeError>;
}
#[macro_export]
macro_rules! impl_borrow_decode {
($ty:ty $(, $param:tt)*) => {
impl<'de $(, $param)*, __Context> $crate::BorrowDecode<'de, __Context> for $ty {
fn borrow_decode<D: $crate::de::BorrowDecoder<'de, Context = __Context>>(
decoder: &mut D,
) -> core::result::Result<Self, $crate::error::DecodeError> {
$crate::Decode::decode(decoder)
}
}
};
}
#[macro_export]
macro_rules! impl_borrow_decode_with_context {
($ty:ty, $context:ty $(, $param:tt)*) => {
impl<'de $(, $param)*> $crate::BorrowDecode<'de, $context> for $ty {
fn borrow_decode<D: $crate::de::BorrowDecoder<'de, Context = $context>>(
decoder: &mut D,
) -> core::result::Result<Self, $crate::error::DecodeError> {
$crate::Decode::decode(decoder)
}
}
};
}
pub trait Decoder: Sealed {
type R: Reader;
type C: Config;
type Context;
fn context(&mut self) -> &mut Self::Context;
fn with_context<C>(&mut self, context: C) -> WithContext<'_, Self, C> {
WithContext {
decoder: self,
context,
}
}
fn reader(&mut self) -> &mut Self::R;
fn config(&self) -> &Self::C;
fn claim_bytes_read(&mut self, n: usize) -> Result<(), DecodeError>;
fn claim_container_read<T>(&mut self, len: usize) -> Result<(), DecodeError> {
if <Self::C as InternalLimitConfig>::LIMIT.is_some() {
match len.checked_mul(core::mem::size_of::<T>()) {
Some(val) => self.claim_bytes_read(val),
None => Err(DecodeError::LimitExceeded),
}
} else {
Ok(())
}
}
fn unclaim_bytes_read(&mut self, n: usize);
}
pub trait BorrowDecoder<'de>: Decoder {
type BR: BorrowReader<'de>;
fn borrow_reader(&mut self) -> &mut Self::BR;
}
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)
}
#[inline]
fn claim_bytes_read(&mut self, n: usize) -> Result<(), DecodeError> {
T::claim_bytes_read(self, n)
}
#[inline]
fn unclaim_bytes_read(&mut self, n: usize) {
T::unclaim_bytes_read(self, n)
}
fn context(&mut self) -> &mut Self::Context {
T::context(self)
}
}
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]
pub(crate) fn decode_option_variant<D: Decoder>(
decoder: &mut D,
type_name: &'static str,
) -> Result<Option<()>, DecodeError> {
let is_some = u8::decode(decoder)?;
match is_some {
0 => Ok(None),
1 => Ok(Some(())),
x => Err(DecodeError::UnexpectedVariant {
found: x as u32,
allowed: &crate::error::AllowedEnumVariants::Range { max: 1, min: 0 },
type_name,
}),
}
}
#[inline]
pub(crate) fn decode_slice_len<D: Decoder>(decoder: &mut D) -> Result<usize, DecodeError> {
let v = u64::decode(decoder)?;
v.try_into().map_err(|_| DecodeError::OutsideUsizeRange(v))
}