use core::marker::PhantomData;
pub(crate) use self::endian::BincodeByteOrder;
pub(crate) use self::int::IntEncoding;
pub(crate) use self::internal::InternalOptions;
pub(crate) use self::limit::SizeLimit;
pub(crate) use self::trailing::TrailingBytes;
pub use self::endian::{BigEndian, LittleEndian, NativeEndian};
pub use self::int::{FixintEncoding, VarintEncoding};
pub use self::limit::{Bounded, Infinite, LimitError};
pub use self::trailing::{AllowTrailing, RejectTrailing};
use crate::{
deserialize::DeserializeError,
serialize::SerializeError,
traits::{CoreRead, CoreWrite},
};
mod endian;
mod int;
mod internal;
mod limit;
mod trailing;
#[derive(Copy, Clone)]
pub struct DefaultOptions(Infinite);
impl DefaultOptions {
pub fn new() -> DefaultOptions {
DefaultOptions(Infinite)
}
}
impl Default for DefaultOptions {
fn default() -> Self {
Self::new()
}
}
impl InternalOptions for DefaultOptions {
type Limit = Infinite;
type Endian = LittleEndian;
type IntEncoding = VarintEncoding;
type Trailing = RejectTrailing;
#[inline(always)]
fn limit(&mut self) -> &mut Infinite {
&mut self.0
}
}
pub trait Options: InternalOptions + Sized {
fn with_no_limit(self) -> WithOtherLimit<Self, Infinite> {
WithOtherLimit::new(self, Infinite)
}
fn with_limit(self, limit: u64) -> WithOtherLimit<Self, Bounded> {
WithOtherLimit::new(self, Bounded(limit))
}
fn with_little_endian(self) -> WithOtherEndian<Self, LittleEndian> {
WithOtherEndian::new(self)
}
fn with_big_endian(self) -> WithOtherEndian<Self, BigEndian> {
WithOtherEndian::new(self)
}
fn with_native_endian(self) -> WithOtherEndian<Self, NativeEndian> {
WithOtherEndian::new(self)
}
fn with_varint_encoding(self) -> WithOtherIntEncoding<Self, VarintEncoding> {
WithOtherIntEncoding::new(self)
}
fn with_fixint_encoding(self) -> WithOtherIntEncoding<Self, FixintEncoding> {
WithOtherIntEncoding::new(self)
}
fn reject_trailing_bytes(self) -> WithOtherTrailing<Self, RejectTrailing> {
WithOtherTrailing::new(self)
}
fn allow_trailing_bytes(self) -> WithOtherTrailing<Self, AllowTrailing> {
WithOtherTrailing::new(self)
}
#[inline(always)]
fn serialized_size<T: ?Sized + serde::Serialize>(
self,
t: &T,
) -> Result<usize, SerializeError<()>> {
crate::serialize::serialize_size(t, self)
}
#[inline(always)]
fn serialize_into<W: CoreWrite, T: ?Sized + serde::Serialize>(
self,
w: W,
t: &T,
) -> Result<(), SerializeError<W>> {
crate::serialize::serialize(t, w, self)
}
#[inline(always)]
fn deserialize<'a, T: serde::Deserialize<'a>>(
self,
bytes: &'a [u8],
) -> Result<T, DeserializeError<'a, &'a [u8]>> {
crate::deserialize::deserialize(bytes, self)
}
#[doc(hidden)]
#[inline(always)]
fn deserialize_in_place<'a, R, T>(
self,
reader: R,
place: &mut T,
) -> Result<(), DeserializeError<'a, R>>
where
R: CoreRead<'a> + 'a,
T: serde::de::Deserialize<'a>,
{
*place = crate::deserialize::deserialize(reader, self)?;
Ok(())
}
#[inline(always)]
#[cfg(feature = "alloc")]
fn deserialize_from<'de, R: CoreRead<'de> + 'de, T: serde::de::DeserializeOwned>(
self,
reader: R,
) -> Result<T, DeserializeError<'de, R>> {
crate::deserialize::deserialize(reader, self)
}
}
impl<T: InternalOptions> Options for T {}
#[derive(Clone, Copy)]
pub struct WithOtherLimit<O: Options, L: SizeLimit> {
_options: O,
pub(crate) new_limit: L,
}
#[derive(Clone, Copy)]
pub struct WithOtherEndian<O: Options, E: BincodeByteOrder> {
options: O,
_endian: PhantomData<E>,
}
pub struct WithOtherIntEncoding<O: Options, I: IntEncoding> {
options: O,
_length: PhantomData<I>,
}
pub struct WithOtherTrailing<O: Options, T: TrailingBytes> {
options: O,
_trailing: PhantomData<T>,
}
impl<O: Options, L: SizeLimit> WithOtherLimit<O, L> {
#[inline(always)]
pub(crate) fn new(options: O, limit: L) -> WithOtherLimit<O, L> {
WithOtherLimit {
_options: options,
new_limit: limit,
}
}
}
impl<O: Options, E: BincodeByteOrder> WithOtherEndian<O, E> {
#[inline(always)]
pub(crate) fn new(options: O) -> WithOtherEndian<O, E> {
WithOtherEndian {
options,
_endian: PhantomData,
}
}
}
impl<O: Options, I: IntEncoding> WithOtherIntEncoding<O, I> {
#[inline(always)]
pub(crate) fn new(options: O) -> WithOtherIntEncoding<O, I> {
WithOtherIntEncoding {
options,
_length: PhantomData,
}
}
}
impl<O: Options, T: TrailingBytes> WithOtherTrailing<O, T> {
#[inline(always)]
pub(crate) fn new(options: O) -> WithOtherTrailing<O, T> {
WithOtherTrailing {
options,
_trailing: PhantomData,
}
}
}
impl<O: Options, E: BincodeByteOrder + 'static> InternalOptions for WithOtherEndian<O, E> {
type Limit = O::Limit;
type Endian = E;
type IntEncoding = O::IntEncoding;
type Trailing = O::Trailing;
#[inline(always)]
fn limit(&mut self) -> &mut O::Limit {
self.options.limit()
}
}
impl<O: Options, L: SizeLimit + 'static> InternalOptions for WithOtherLimit<O, L> {
type Limit = L;
type Endian = O::Endian;
type IntEncoding = O::IntEncoding;
type Trailing = O::Trailing;
fn limit(&mut self) -> &mut L {
&mut self.new_limit
}
}
impl<O: Options, I: IntEncoding + 'static> InternalOptions for WithOtherIntEncoding<O, I> {
type Limit = O::Limit;
type Endian = O::Endian;
type IntEncoding = I;
type Trailing = O::Trailing;
fn limit(&mut self) -> &mut O::Limit {
self.options.limit()
}
}
impl<O: Options, T: TrailingBytes + 'static> InternalOptions for WithOtherTrailing<O, T> {
type Limit = O::Limit;
type Endian = O::Endian;
type IntEncoding = O::IntEncoding;
type Trailing = T;
fn limit(&mut self) -> &mut O::Limit {
self.options.limit()
}
}