mod decoder;
mod impl_core;
mod impl_tuples;
mod impls;
use self::read::{BorrowReader, Reader};
use crate::{
config::{Config, InternalLimitConfig},
error::DecodeError,
utils::Sealed,
};
pub mod read;
pub use self::decoder::DecoderImpl;
pub trait Decode: for<'de> BorrowDecode<'de> {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError>;
}
pub trait BorrowDecode<'de>: Sized {
fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError>;
}
impl<'de, T: Decode> BorrowDecode<'de> for T {
fn borrow_decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
Decode::decode(decoder)
}
}
pub trait Decoder: Sealed {
type R: Reader;
type C: Config;
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<'a, T> Decoder for &'a mut T
where
T: Decoder,
{
type R = T::R;
type C = T::C;
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)
}
}
impl<'a, 'de, T> BorrowDecoder<'de> for &'a 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 u8,
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))
}