use super::{read::Reader, Decode, Decoder};
use crate::{
config::{Endianness, IntEncoding, InternalEndianConfig, InternalIntEncodingConfig},
error::Error,
};
use core::marker::PhantomData;
impl Decode for () {
fn decode<D: Decoder<Context = ()>>(_: &mut D) -> Result<Self, Error> {
Ok(())
}
}
impl<T: ?Sized> Decode for PhantomData<T> {
fn decode<D: Decoder<Context = ()>>(_: &mut D) -> Result<Self, Error> {
Ok(PhantomData)
}
}
impl<'__de, T: ?Sized> crate::de::BorrowDecode<'__de> for PhantomData<T> {
fn borrow_decode<D: crate::de::BorrowDecoder<'__de, Context = ()>>(
_decoder: &mut D,
) -> Result<Self, crate::error::Error> {
Ok(PhantomData)
}
}
impl Decode for bool {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
match u8::decode(decoder)? {
0 => Ok(false),
1 => Ok(true),
v => Err(Error::InvalidBooleanValue(v)),
}
}
}
impl Decode for u8 {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
decoder.claim_bytes_read(1)?;
let mut bytes = [0u8; 1];
decoder.reader().read(&mut bytes)?;
Ok(bytes[0])
}
}
impl Decode for u16 {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
decoder.claim_bytes_read(2)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
crate::varint::varint_decode_u16(decoder.reader(), D::C::ENDIAN)
}
IntEncoding::Fixed => {
let mut bytes = [0u8; 2];
decoder.reader().read(&mut bytes)?;
Ok(match D::C::ENDIAN {
Endianness::Big => u16::from_be_bytes(bytes),
Endianness::Little => u16::from_le_bytes(bytes),
})
}
}
}
}
impl Decode for u32 {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
decoder.claim_bytes_read(4)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
crate::varint::varint_decode_u32(decoder.reader(), D::C::ENDIAN)
}
IntEncoding::Fixed => {
let mut bytes = [0u8; 4];
decoder.reader().read(&mut bytes)?;
Ok(match D::C::ENDIAN {
Endianness::Big => u32::from_be_bytes(bytes),
Endianness::Little => u32::from_le_bytes(bytes),
})
}
}
}
}
impl Decode for u64 {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
decoder.claim_bytes_read(8)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
crate::varint::varint_decode_u64(decoder.reader(), D::C::ENDIAN)
}
IntEncoding::Fixed => {
let mut bytes = [0u8; 8];
decoder.reader().read(&mut bytes)?;
Ok(match D::C::ENDIAN {
Endianness::Big => u64::from_be_bytes(bytes),
Endianness::Little => u64::from_le_bytes(bytes),
})
}
}
}
}
impl Decode for u128 {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
decoder.claim_bytes_read(16)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
crate::varint::varint_decode_u128(decoder.reader(), D::C::ENDIAN)
}
IntEncoding::Fixed => {
let mut bytes = [0u8; 16];
decoder.reader().read(&mut bytes)?;
Ok(match D::C::ENDIAN {
Endianness::Big => u128::from_be_bytes(bytes),
Endianness::Little => u128::from_le_bytes(bytes),
})
}
}
}
}
impl Decode for usize {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
decoder.claim_bytes_read(8)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
crate::varint::varint_decode_usize(decoder.reader(), D::C::ENDIAN)
}
IntEncoding::Fixed => {
let mut bytes = [0u8; 8];
decoder.reader().read(&mut bytes)?;
let value = match D::C::ENDIAN {
Endianness::Big => u64::from_be_bytes(bytes),
Endianness::Little => u64::from_le_bytes(bytes),
};
usize::try_from(value).map_err(|_| Error::OutsideUsizeRange(value))
}
}
}
}
impl Decode for i8 {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
decoder.claim_bytes_read(1)?;
let mut bytes = [0u8; 1];
decoder.reader().read(&mut bytes)?;
Ok(bytes[0] as i8)
}
}
impl Decode for i16 {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
decoder.claim_bytes_read(2)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
crate::varint::varint_decode_i16(decoder.reader(), D::C::ENDIAN)
}
IntEncoding::Fixed => {
let mut bytes = [0u8; 2];
decoder.reader().read(&mut bytes)?;
Ok(match D::C::ENDIAN {
Endianness::Big => i16::from_be_bytes(bytes),
Endianness::Little => i16::from_le_bytes(bytes),
})
}
}
}
}
impl Decode for i32 {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
decoder.claim_bytes_read(4)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
crate::varint::varint_decode_i32(decoder.reader(), D::C::ENDIAN)
}
IntEncoding::Fixed => {
let mut bytes = [0u8; 4];
decoder.reader().read(&mut bytes)?;
Ok(match D::C::ENDIAN {
Endianness::Big => i32::from_be_bytes(bytes),
Endianness::Little => i32::from_le_bytes(bytes),
})
}
}
}
}
impl Decode for i64 {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
decoder.claim_bytes_read(8)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
crate::varint::varint_decode_i64(decoder.reader(), D::C::ENDIAN)
}
IntEncoding::Fixed => {
let mut bytes = [0u8; 8];
decoder.reader().read(&mut bytes)?;
Ok(match D::C::ENDIAN {
Endianness::Big => i64::from_be_bytes(bytes),
Endianness::Little => i64::from_le_bytes(bytes),
})
}
}
}
}
impl Decode for i128 {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
decoder.claim_bytes_read(16)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
crate::varint::varint_decode_i128(decoder.reader(), D::C::ENDIAN)
}
IntEncoding::Fixed => {
let mut bytes = [0u8; 16];
decoder.reader().read(&mut bytes)?;
Ok(match D::C::ENDIAN {
Endianness::Big => i128::from_be_bytes(bytes),
Endianness::Little => i128::from_le_bytes(bytes),
})
}
}
}
}
impl Decode for isize {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
decoder.claim_bytes_read(8)?;
match D::C::INT_ENCODING {
IntEncoding::Variable => {
crate::varint::varint_decode_isize(decoder.reader(), D::C::ENDIAN)
}
IntEncoding::Fixed => {
let mut bytes = [0u8; 8];
decoder.reader().read(&mut bytes)?;
let value = match D::C::ENDIAN {
Endianness::Big => i64::from_be_bytes(bytes),
Endianness::Little => i64::from_le_bytes(bytes),
};
isize::try_from(value).map_err(|_| Error::OutsideUsizeRange(value as u64))
}
}
}
}
impl Decode for f32 {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
decoder.claim_bytes_read(4)?;
let mut bytes = [0u8; 4];
decoder.reader().read(&mut bytes)?;
Ok(match D::C::ENDIAN {
Endianness::Big => f32::from_be_bytes(bytes),
Endianness::Little => f32::from_le_bytes(bytes),
})
}
}
impl Decode for f64 {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
decoder.claim_bytes_read(8)?;
let mut bytes = [0u8; 8];
decoder.reader().read(&mut bytes)?;
Ok(match D::C::ENDIAN {
Endianness::Big => f64::from_be_bytes(bytes),
Endianness::Little => f64::from_le_bytes(bytes),
})
}
}
#[inline]
fn decode_array_with<T, const N: usize, F>(mut decode_elem: F) -> Result<[T; N], Error>
where
F: FnMut() -> Result<T, Error>,
{
use core::mem::MaybeUninit;
struct Guard<'a, T, const N: usize> {
array: &'a mut [MaybeUninit<T>; N],
initialized: usize,
}
impl<T, const N: usize> Drop for Guard<'_, T, N> {
fn drop(&mut self) {
for slot in self.array[..self.initialized].iter_mut() {
unsafe { core::ptr::drop_in_place(slot.as_mut_ptr()) };
}
}
}
let mut array: [MaybeUninit<T>; N] =
unsafe { MaybeUninit::<[MaybeUninit<T>; N]>::uninit().assume_init() };
let mut guard = Guard {
array: &mut array,
initialized: 0,
};
while guard.initialized < N {
let value = decode_elem()?;
guard.array[guard.initialized].write(value);
guard.initialized += 1;
}
core::mem::forget(guard);
Ok(unsafe { core::mem::transmute_copy::<_, [T; N]>(&array) })
}
impl<T: Decode, const N: usize> Decode for [T; N] {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
decoder.claim_bytes_read(core::mem::size_of::<[T; N]>())?;
if unty::type_equal::<T, u8>() {
let mut buf = [0u8; N];
decoder.reader().read(&mut buf)?;
let ptr = (&mut buf as *mut [u8; N]).cast::<[T; N]>();
Ok(unsafe { ptr.read() })
} else {
decode_array_with::<T, N, _>(|| {
decoder.unclaim_bytes_read(core::mem::size_of::<T>());
T::decode(decoder)
})
}
}
}
impl<T: Decode> Decode for Option<T> {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
let variant = u8::decode(decoder)?;
match variant {
0 => Ok(None),
1 => Ok(Some(T::decode(decoder)?)),
_ => Err(Error::InvalidData {
message: "Invalid Option variant",
}),
}
}
}
impl<T: Decode, U: Decode> Decode for Result<T, U> {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
let variant = u32::decode(decoder)?;
match variant {
0 => Ok(Ok(T::decode(decoder)?)),
1 => Ok(Err(U::decode(decoder)?)),
_ => Err(Error::InvalidData {
message: "Invalid Result variant",
}),
}
}
}
use core::cell::{Cell, RefCell};
impl<T: Decode> Decode for Cell<T> {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
Ok(Cell::new(T::decode(decoder)?))
}
}
impl<T: Decode> Decode for RefCell<T> {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
Ok(RefCell::new(T::decode(decoder)?))
}
}
use core::num::{
NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
};
use crate::error::IntegerType;
macro_rules! impl_decode_nonzero {
($nonzero:ty, $inner:ty, $int_type:expr) => {
impl Decode for $nonzero {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
let value = <$inner>::decode(decoder)?;
<$nonzero>::new(value).ok_or(Error::NonZeroTypeIsZero {
non_zero_type: $int_type,
})
}
}
};
}
impl_decode_nonzero!(NonZeroU8, u8, IntegerType::U8);
impl_decode_nonzero!(NonZeroU16, u16, IntegerType::U16);
impl_decode_nonzero!(NonZeroU32, u32, IntegerType::U32);
impl_decode_nonzero!(NonZeroU64, u64, IntegerType::U64);
impl_decode_nonzero!(NonZeroU128, u128, IntegerType::U128);
impl_decode_nonzero!(NonZeroUsize, usize, IntegerType::Usize);
impl_decode_nonzero!(NonZeroI8, i8, IntegerType::I8);
impl_decode_nonzero!(NonZeroI16, i16, IntegerType::I16);
impl_decode_nonzero!(NonZeroI32, i32, IntegerType::I32);
impl_decode_nonzero!(NonZeroI64, i64, IntegerType::I64);
impl_decode_nonzero!(NonZeroI128, i128, IntegerType::I128);
impl_decode_nonzero!(NonZeroIsize, isize, IntegerType::Isize);
impl Decode for core::cmp::Ordering {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
match i8::decode(decoder)? {
-1 => Ok(core::cmp::Ordering::Less),
0 => Ok(core::cmp::Ordering::Equal),
1 => Ok(core::cmp::Ordering::Greater),
other => Err(Error::UnexpectedVariant {
type_name: "Ordering",
found: other as u8 as u32,
}),
}
}
}
impl Decode for core::convert::Infallible {
fn decode<D: Decoder<Context = ()>>(_decoder: &mut D) -> Result<Self, Error> {
Err(Error::InvalidData {
message: "Infallible cannot be decoded",
})
}
}
impl<B: Decode, C: Decode> Decode for core::ops::ControlFlow<B, C> {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
match u32::decode(decoder)? {
0 => Ok(core::ops::ControlFlow::Continue(C::decode(decoder)?)),
1 => Ok(core::ops::ControlFlow::Break(B::decode(decoder)?)),
other => Err(Error::UnexpectedVariant {
type_name: "ControlFlow",
found: other,
}),
}
}
}
use core::cmp::Reverse;
use core::num::Wrapping;
impl<T: Decode> Decode for Wrapping<T> {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
Ok(Wrapping(T::decode(decoder)?))
}
}
impl<T: Decode> Decode for Reverse<T> {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
Ok(Reverse(T::decode(decoder)?))
}
}
use core::num::Saturating;
impl<T: Decode> Decode for Saturating<T> {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
Ok(Saturating(T::decode(decoder)?))
}
}
use core::ops::{Bound, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive};
impl<T: Decode> Decode for Range<T> {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
Ok(Range {
start: T::decode(decoder)?,
end: T::decode(decoder)?,
})
}
}
impl<T: Decode> Decode for RangeInclusive<T> {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
let start = T::decode(decoder)?;
let end = T::decode(decoder)?;
Ok(RangeInclusive::new(start, end))
}
}
impl<T: Decode> Decode for Bound<T> {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
let variant = u8::decode(decoder)?;
match variant {
0 => Ok(Bound::Unbounded),
1 => Ok(Bound::Included(T::decode(decoder)?)),
2 => Ok(Bound::Excluded(T::decode(decoder)?)),
_ => Err(Error::InvalidData {
message: "Invalid Bound variant",
}),
}
}
}
impl Decode for RangeFull {
fn decode<D: Decoder<Context = ()>>(_decoder: &mut D) -> Result<Self, Error> {
Ok(..)
}
}
impl<T: Decode> Decode for RangeFrom<T> {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
let start = T::decode(decoder)?;
Ok(start..)
}
}
impl<T: Decode> Decode for RangeTo<T> {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
let end = T::decode(decoder)?;
Ok(..end)
}
}
impl<T: Decode> Decode for RangeToInclusive<T> {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
let end = T::decode(decoder)?;
Ok(..=end)
}
}
const UTF8_CHAR_WIDTH: [u8; 256] = [
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ];
#[inline]
const fn utf8_char_width(byte: u8) -> usize {
UTF8_CHAR_WIDTH[byte as usize] as usize
}
impl Decode for char {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
let mut array = [0u8; 4];
decoder.reader().read(&mut array[..1])?;
let width = utf8_char_width(array[0]);
if width == 0 {
return Err(Error::InvalidCharEncoding(array));
}
decoder.claim_bytes_read(width)?;
if width == 1 {
return Ok(array[0] as char);
}
decoder.reader().read(&mut array[1..width])?;
core::str::from_utf8(&array[..width])
.ok()
.and_then(|s| s.chars().next())
.ok_or(Error::InvalidCharEncoding(array))
}
}
impl Decode for core::time::Duration {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
let secs = u64::decode(decoder)?;
let nanos = u32::decode(decoder)?;
if nanos >= 1_000_000_000 {
return Err(Error::InvalidData {
message: "Duration subsec_nanos out of range (must be < 1_000_000_000)",
});
}
Ok(core::time::Duration::new(secs, nanos))
}
}
#[cfg(feature = "std")]
impl Decode for std::time::SystemTime {
fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, Error> {
let secs = i64::decode(decoder)?;
let nanos = u32::decode(decoder)?;
if nanos >= 1_000_000_000 {
return Err(Error::InvalidData {
message: "SystemTime subsec_nanos out of range (must be < 1_000_000_000)",
});
}
let epoch = std::time::SystemTime::UNIX_EPOCH;
if secs >= 0 {
let dur = std::time::Duration::new(secs as u64, nanos);
epoch.checked_add(dur).ok_or(Error::InvalidData {
message: "SystemTime value overflow (too far in the future)",
})
} else {
let abs_secs = (-(secs + 1)) as u64;
let remaining_nanos = if nanos == 0 {
0u32
} else {
1_000_000_000u32 - nanos
};
let back = std::time::Duration::new(abs_secs + 1, 0);
let fwd = std::time::Duration::new(0, remaining_nanos);
let t = epoch.checked_sub(back).ok_or(Error::InvalidData {
message: "SystemTime value underflow (too far in the past)",
})?;
t.checked_add(fwd).ok_or(Error::InvalidData {
message: "SystemTime value overflow after nanos adjustment",
})
}
}
}
crate::impl_borrow_decode!(());
crate::impl_borrow_decode!(bool);
crate::impl_borrow_decode!(u8);
crate::impl_borrow_decode!(u16);
crate::impl_borrow_decode!(u32);
crate::impl_borrow_decode!(u64);
crate::impl_borrow_decode!(u128);
crate::impl_borrow_decode!(usize);
crate::impl_borrow_decode!(i8);
crate::impl_borrow_decode!(i16);
crate::impl_borrow_decode!(i32);
crate::impl_borrow_decode!(i64);
crate::impl_borrow_decode!(i128);
crate::impl_borrow_decode!(isize);
crate::impl_borrow_decode!(f32);
crate::impl_borrow_decode!(f64);
crate::impl_borrow_decode!(char);
crate::impl_borrow_decode!(core::cmp::Ordering);
crate::impl_borrow_decode!(core::convert::Infallible);
crate::impl_borrow_decode!(NonZeroU8);
crate::impl_borrow_decode!(NonZeroU16);
crate::impl_borrow_decode!(NonZeroU32);
crate::impl_borrow_decode!(NonZeroU64);
crate::impl_borrow_decode!(NonZeroU128);
crate::impl_borrow_decode!(NonZeroUsize);
crate::impl_borrow_decode!(NonZeroI8);
crate::impl_borrow_decode!(NonZeroI16);
crate::impl_borrow_decode!(NonZeroI32);
crate::impl_borrow_decode!(NonZeroI64);
crate::impl_borrow_decode!(NonZeroI128);
crate::impl_borrow_decode!(NonZeroIsize);
crate::impl_borrow_decode!(core::time::Duration);
#[cfg(feature = "std")]
impl<'de> crate::de::BorrowDecode<'de> for std::time::SystemTime {
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, crate::error::Error> {
<std::time::SystemTime as crate::de::Decode>::decode(decoder)
}
}
impl<'de, T: crate::de::BorrowDecode<'de>> crate::de::BorrowDecode<'de> for Wrapping<T> {
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, crate::error::Error> {
Ok(Wrapping(T::borrow_decode(decoder)?))
}
}
impl<'de, T: crate::de::BorrowDecode<'de>> crate::de::BorrowDecode<'de> for Reverse<T> {
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, crate::error::Error> {
Ok(Reverse(T::borrow_decode(decoder)?))
}
}
impl<'de, T: crate::de::BorrowDecode<'de>> crate::de::BorrowDecode<'de> for Saturating<T> {
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, crate::error::Error> {
Ok(Saturating(T::borrow_decode(decoder)?))
}
}
impl<'de, T: crate::de::BorrowDecode<'de>> crate::de::BorrowDecode<'de> for core::ops::Range<T> {
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, crate::error::Error> {
Ok(core::ops::Range {
start: T::borrow_decode(decoder)?,
end: T::borrow_decode(decoder)?,
})
}
}
impl<'de, T: crate::de::BorrowDecode<'de>> crate::de::BorrowDecode<'de>
for core::ops::RangeInclusive<T>
{
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, crate::error::Error> {
let start = T::borrow_decode(decoder)?;
let end = T::borrow_decode(decoder)?;
Ok(core::ops::RangeInclusive::new(start, end))
}
}
impl<'de, T: crate::de::BorrowDecode<'de>> crate::de::BorrowDecode<'de> for core::ops::Bound<T> {
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, crate::error::Error> {
let variant = u8::decode(decoder)?;
match variant {
0 => Ok(core::ops::Bound::Unbounded),
1 => Ok(core::ops::Bound::Included(T::borrow_decode(decoder)?)),
2 => Ok(core::ops::Bound::Excluded(T::borrow_decode(decoder)?)),
_ => Err(crate::error::Error::InvalidData {
message: "Invalid Bound variant",
}),
}
}
}
impl<'de> crate::de::BorrowDecode<'de> for RangeFull {
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, crate::error::Error> {
Decode::decode(decoder)
}
}
impl<'de, T: crate::de::BorrowDecode<'de>> crate::de::BorrowDecode<'de> for RangeFrom<T> {
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, crate::error::Error> {
let start = T::borrow_decode(decoder)?;
Ok(start..)
}
}
impl<'de, T: crate::de::BorrowDecode<'de>> crate::de::BorrowDecode<'de> for RangeTo<T> {
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, crate::error::Error> {
let end = T::borrow_decode(decoder)?;
Ok(..end)
}
}
impl<'de, T: crate::de::BorrowDecode<'de>> crate::de::BorrowDecode<'de> for RangeToInclusive<T> {
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, crate::error::Error> {
let end = T::borrow_decode(decoder)?;
Ok(..=end)
}
}
impl<'de, T: crate::de::BorrowDecode<'de>> crate::de::BorrowDecode<'de> for core::cell::Cell<T> {
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, crate::error::Error> {
Ok(core::cell::Cell::new(T::borrow_decode(decoder)?))
}
}
impl<'de, T: crate::de::BorrowDecode<'de>> crate::de::BorrowDecode<'de> for core::cell::RefCell<T> {
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, crate::error::Error> {
Ok(core::cell::RefCell::new(T::borrow_decode(decoder)?))
}
}
impl<'__de, B, C> crate::de::BorrowDecode<'__de> for core::ops::ControlFlow<B, C>
where
B: crate::de::BorrowDecode<'__de>,
C: crate::de::BorrowDecode<'__de>,
{
fn borrow_decode<D: crate::de::BorrowDecoder<'__de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, crate::error::Error> {
let discriminant = u32::decode(decoder)?;
match discriminant {
0 => Ok(core::ops::ControlFlow::Continue(C::borrow_decode(decoder)?)),
1 => Ok(core::ops::ControlFlow::Break(B::borrow_decode(decoder)?)),
other => Err(crate::error::Error::UnexpectedVariant {
type_name: "ControlFlow",
found: other,
}),
}
}
}
impl<'de, T, const N: usize> crate::de::BorrowDecode<'de> for [T; N]
where
T: crate::de::BorrowDecode<'de>,
{
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, crate::error::Error> {
decoder.claim_bytes_read(core::mem::size_of::<[T; N]>())?;
if unty::type_equal::<T, u8>() {
let mut buf = [0u8; N];
decoder.reader().read(&mut buf)?;
let ptr = (&mut buf as *mut [u8; N]).cast::<[T; N]>();
Ok(unsafe { ptr.read() })
} else {
decode_array_with::<T, N, _>(|| {
decoder.unclaim_bytes_read(core::mem::size_of::<T>());
T::borrow_decode(decoder)
})
}
}
}
impl<'de, T, U> crate::de::BorrowDecode<'de> for Result<T, U>
where
T: crate::de::BorrowDecode<'de>,
U: crate::de::BorrowDecode<'de>,
{
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, crate::error::Error> {
let variant = u32::decode(decoder)?;
match variant {
0 => Ok(Ok(T::borrow_decode(decoder)?)),
1 => Ok(Err(U::borrow_decode(decoder)?)),
_ => Err(Error::InvalidData {
message: "Invalid Result variant",
}),
}
}
}
impl<'de, T> crate::de::BorrowDecode<'de> for Option<T>
where
T: crate::de::BorrowDecode<'de>,
{
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, Error> {
let variant = u8::decode(decoder)?;
match variant {
0 => Ok(None),
1 => Ok(Some(T::borrow_decode(decoder)?)),
_ => Err(Error::InvalidData {
message: "Invalid Option variant",
}),
}
}
}
impl<'de> crate::de::BorrowDecode<'de> for &'de [u8] {
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, Error> {
use crate::de::BorrowReader;
let len = crate::de::decode_slice_len(decoder)?;
decoder.claim_bytes_read(len)?;
let bytes = decoder.borrow_reader().take_bytes(len)?;
Ok(bytes)
}
}
impl<'de> crate::de::BorrowDecode<'de> for &'de str {
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, Error> {
use crate::de::BorrowReader;
let len = crate::de::decode_slice_len(decoder)?;
decoder.claim_bytes_read(len)?;
let bytes = decoder.borrow_reader().take_bytes(len)?;
core::str::from_utf8(bytes).map_err(Error::from)
}
}
impl<'de> crate::de::BorrowDecode<'de> for &'de [i8] {
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, Error> {
use crate::de::BorrowReader;
let len = crate::de::decode_slice_len(decoder)?;
decoder.claim_bytes_read(len)?;
let bytes: &'de [u8] = decoder.borrow_reader().take_bytes(len)?;
let signed_bytes: &'de [i8] =
unsafe { core::slice::from_raw_parts(bytes.as_ptr() as *const i8, bytes.len()) };
Ok(signed_bytes)
}
}
impl<'de, T> crate::de::BorrowDecode<'de> for &'de [T]
where
T: crate::de::BorrowableSliceElement,
{
fn borrow_decode<D: crate::de::BorrowDecoder<'de, Context = ()>>(
decoder: &mut D,
) -> Result<Self, Error> {
use crate::config::Config;
use crate::de::BorrowReader;
let len = crate::de::decode_slice_len(decoder)?;
decoder.claim_container_read::<T>(len)?;
let cfg = decoder.config();
if cfg.int_encoding() != IntEncoding::Fixed {
return Err(Error::InvalidData {
message: "borrow-decode of &[T] requires IntEncoding::Fixed; \
varint-encoded payloads do not match in-memory layout",
});
}
if !T::endianness_compatible(cfg.endianness()) {
return Err(Error::InvalidData {
message: "borrow-decode of &[T] requires native endianness; \
use Vec<T> for cross-endian decoding",
});
}
let elem_size = core::mem::size_of::<T>();
let byte_count = len.checked_mul(elem_size).ok_or(Error::InvalidData {
message: "borrow-decode of &[T]: length × element-size overflows usize",
})?;
let bytes = decoder.borrow_reader().take_bytes(byte_count)?;
let align = core::mem::align_of::<T>();
if (bytes.as_ptr() as usize) % align != 0 {
return Err(Error::InvalidData {
message: "borrow-decode of &[T]: buffer is not aligned to align_of::<T>(); \
use Vec<T> instead",
});
}
let slice: &'de [T] =
unsafe { core::slice::from_raw_parts(bytes.as_ptr() as *const T, len) };
Ok(slice)
}
}