mod decoder;
mod impl_core;
mod impl_tuples;
mod impls;
use self::decoder::WithContext;
use self::read::BorrowReader;
use self::read::Reader;
use crate::config::Config;
use crate::config::InternalLimitConfig;
use crate::error::DecodeError;
use crate::utils::Sealed;
pub mod bit_reader;
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 + crate::error_path::BincodeErrorPathCovered<0> {
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> {
Self::assert_covered();
if <Self::C as InternalLimitConfig>::LIMIT.is_some() {
len.checked_mul(core::mem::size_of::<T>()).map_or_else(
|| crate::error::cold_decode_error_limit_exceeded(),
|val| self.claim_bytes_read(val),
)
} 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> crate::error_path::BincodeErrorPathCovered<0> for &mut T where
T: crate::error_path::BincodeErrorPathCovered<0>
{
}
impl<T> Decoder for &mut T
where
T: Decoder,
{
type C = T::C;
type Context = T::Context;
type R = T::R;
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> {
D::assert_covered();
let is_some = u8::decode(decoder)?;
match is_some {
| 0 => Ok(None),
| 1 => Ok(Some(())),
| x => {
crate::error::cold_decode_error_unexpected_variant(
type_name,
&crate::error::AllowedEnumVariants::Range { max: 1, min: 0 },
u32::from(x),
)
},
}
}
#[inline]
pub(crate) fn decode_slice_len<D: Decoder>(decoder: &mut D) -> Result<usize, DecodeError> {
D::assert_covered();
let v = u64::decode(decoder)?;
v.try_into()
.map_err(|_| crate::error::cold_decode_error_outside_usize_range::<()>(v).unwrap_err())
}