use core::num::{
NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU128, NonZeroU16,
NonZeroU32, NonZeroU64, NonZeroU8,
};
use bitstream_io::{BitRead, BitWrite, Endianness};
use crate::{BitDecode, BitEncode, Bits, Result};
impl<Ctx, const C: u32> BitDecode<Ctx, Bits<C>> for bool {
fn decode<R, E>(read: &mut R, _: &mut Ctx, _: Bits<C>) -> Result<Self>
where
R: BitRead,
E: Endianness,
{
if read.read::<C, u8>()? == 0 {
Ok(false)
} else {
Ok(true)
}
}
}
impl<Ctx, const C: u32> BitEncode<Ctx, Bits<C>> for bool {
fn encode<W, E>(&self, write: &mut W, _: &mut Ctx, _: Bits<C>) -> Result<()>
where
W: BitWrite,
E: Endianness,
{
write.write::<C, u8>((*self).into())?;
Ok(())
}
}
impl<Ctx> BitDecode<Ctx> for bool {
fn decode<R, E>(read: &mut R, _: &mut Ctx, (): ()) -> Result<Self>
where
R: BitRead,
E: Endianness,
{
if read.read_as_to::<E, u8>()? == 0 {
Ok(false)
} else {
Ok(true)
}
}
}
impl<Ctx> BitEncode<Ctx> for bool {
fn encode<W, E>(&self, write: &mut W, _: &mut Ctx, (): ()) -> Result<()>
where
W: BitWrite,
E: Endianness,
{
write.write_as_from::<E, _>(u8::from(*self))?;
Ok(())
}
}
macro_rules! impl_codec_for_numeric_unordered {
($ty:ty => $data_ty:ty) => {
impl<Ctx> $crate::BitDecode<Ctx> for $ty {
fn decode<R, E>(read: &mut R, _: &mut Ctx, (): ()) -> $crate::Result<Self>
where
R: ::bitstream_io::BitRead,
E: ::bitstream_io::Endianness,
{
Ok(::core::convert::TryInto::try_into(
::bitstream_io::BitRead::read_as_to::<E, $data_ty>(read)?,
)?)
}
}
impl<Ctx> $crate::BitEncode<Ctx> for $ty {
fn encode<W, E>(&self, write: &mut W, _: &mut Ctx, (): ()) -> $crate::Result<()>
where
W: ::bitstream_io::BitWrite,
E: ::bitstream_io::Endianness,
{
::bitstream_io::BitWrite::write_as_from::<E, $data_ty>(
write,
::core::convert::TryInto::try_into(*self)?,
)?;
Ok(())
}
}
};
}
macro_rules! impl_codec_for_numeric {
($ty:ty $(: $thru:ident $fallible:tt)? => $data_ty:ty) => {
impl<Ctx> $crate::BitDecode<Ctx> for $ty {
fn decode<R, E>(
read: &mut R,
_: &mut Ctx,
(): (),
) -> $crate::Result<Self>
where
R: ::bitstream_io::BitRead,
E: ::bitstream_io::Endianness,
{
Ok(::core::convert::TryInto::try_into(
$(::core::convert::TryInto::<$thru>::try_into)?(
::bitstream_io::BitRead::read_as_to::<E, $data_ty>(read)?
)$($fallible)?,
)?)
}
}
impl<Ctx> $crate::BitEncode<Ctx> for $ty {
fn encode<W, E>(
&self,
write: &mut W,
_: &mut Ctx,
(): (),
) -> $crate::Result<()>
where
W: ::bitstream_io::BitWrite,
E: ::bitstream_io::Endianness
{
::bitstream_io::BitWrite::write_as_from::<E, $data_ty>(
write,
::core::convert::TryInto::try_into(
$(::core::convert::TryInto::<$thru>::try_into)?(*self)$($fallible)?,
)?,
)?;
Ok(())
}
}
};
}
macro_rules! impl_bitfield_for_numeric {
($ty:ty $(: $thru:ident $fallible:tt)? => $data_ty:ty) => {
impl<Ctx, const C: u32> $crate::BitDecode<Ctx, $crate::Bits<C>> for $ty {
fn decode<R, E>(
read: &mut R,
_: &mut Ctx,
_: $crate::Bits<C>,
) -> $crate::Result<Self>
where
R: ::bitstream_io::BitRead,
E: ::bitstream_io::Endianness,
{
Ok(::core::convert::TryInto::try_into(
$(::core::convert::TryInto::<$thru>::try_into)?(::bitstream_io::BitRead::read::<C, $data_ty>(
read
)$($fallible)?)?,
)?)
}
}
impl<Ctx, const C: u32> $crate::BitEncode<Ctx, $crate::Bits<C>> for $ty {
fn encode<W, E>(
&self,
write: &mut W,
_: &mut Ctx,
_: $crate::Bits<C>,
) -> $crate::Result<()>
where
W: ::bitstream_io::BitWrite,
E: ::bitstream_io::Endianness
{
::bitstream_io::BitWrite::write::<C, $data_ty>(
write,
::core::convert::TryInto::try_into(
$(::core::convert::TryInto::<$thru>::try_into)?(*self)$($fallible)?,
)?,
)?;
Ok(())
}
}
};
}
impl_codec_for_numeric_unordered!(u8 => u8);
impl_codec_for_numeric_unordered!(i8 => i8);
impl_codec_for_numeric_unordered!(NonZeroU8 => u8);
impl_codec_for_numeric_unordered!(NonZeroI8 => i8);
impl_codec_for_numeric!(u16 => u16);
impl_codec_for_numeric!(i16 => i16);
impl_codec_for_numeric!(u32 => u32);
impl_codec_for_numeric!(i32 => i32);
impl_codec_for_numeric!(u64 => u64);
impl_codec_for_numeric!(i64 => i64);
impl_codec_for_numeric!(u128 => u128);
impl_codec_for_numeric!(i128 => i128);
impl_codec_for_numeric!(NonZeroU16 => u16);
impl_codec_for_numeric!(NonZeroI16 => i16);
impl_codec_for_numeric!(NonZeroU32 => u32);
impl_codec_for_numeric!(NonZeroI32 => i32);
impl_codec_for_numeric!(NonZeroU64 => u64);
impl_codec_for_numeric!(NonZeroI64 => i64);
impl_codec_for_numeric!(NonZeroU128 => u128);
impl_codec_for_numeric!(NonZeroI128 => i128);
impl_codec_for_numeric!(f32 => f32);
impl_codec_for_numeric!(f64 => f64);
impl_bitfield_for_numeric!(u8 => u8);
impl_bitfield_for_numeric!(i8 => i8);
impl_bitfield_for_numeric!(u16 => u16);
impl_bitfield_for_numeric!(i16 => i16);
impl_bitfield_for_numeric!(u32 => u32);
impl_bitfield_for_numeric!(i32 => i32);
impl_bitfield_for_numeric!(u64 => u64);
impl_bitfield_for_numeric!(i64 => i64);
impl_bitfield_for_numeric!(u128 => u128);
impl_bitfield_for_numeric!(i128 => i128);
impl_bitfield_for_numeric!(NonZeroU8 => u8);
impl_bitfield_for_numeric!(NonZeroI8 => i8);
impl_bitfield_for_numeric!(NonZeroU16 => u16);
impl_bitfield_for_numeric!(NonZeroI16 => i16);
impl_bitfield_for_numeric!(NonZeroU32 => u32);
impl_bitfield_for_numeric!(NonZeroI32 => i32);
impl_bitfield_for_numeric!(NonZeroU128 => u128);
impl_bitfield_for_numeric!(NonZeroI128 => i128);
#[cfg(target_pointer_width = "16")]
mod size {
use core::num::{NonZeroIsize, NonZeroUsize};
impl_codec_for_numeric!(usize => u16);
impl_bitfield_for_numeric!(usize => u16);
impl_codec_for_numeric!(NonZeroUsize: usize? => u16);
impl_bitfield_for_numeric!(NonZeroUsize: usize? => u16);
impl_codec_for_numeric!(isize => i16);
impl_bitfield_for_numeric!(isize => i16);
impl_codec_for_numeric!(NonZeroIsize: isize? => i16);
impl_bitfield_for_numeric!(NonZeroIsize: isize? => i16);
}
#[cfg(target_pointer_width = "32")]
mod size {
use core::num::{NonZeroIsize, NonZeroUsize};
impl_codec_for_numeric!(usize => u32);
impl_bitfield_for_numeric!(usize => u32);
impl_codec_for_numeric!(NonZeroUsize: usize? => u32);
impl_bitfield_for_numeric!(NonZeroUsize: usize? => u32);
impl_codec_for_numeric!(isize => i32);
impl_bitfield_for_numeric!(isize => i32);
impl_codec_for_numeric!(NonZeroIsize: isize? => i32);
impl_bitfield_for_numeric!(NonZeroIsize: isize? => i32);
}
#[cfg(target_pointer_width = "64")]
mod size {
use core::num::{NonZeroIsize, NonZeroUsize};
impl_codec_for_numeric!(usize => u64);
impl_bitfield_for_numeric!(usize => u64);
impl_codec_for_numeric!(NonZeroUsize: usize? => u64);
impl_bitfield_for_numeric!(NonZeroUsize: usize? => u64);
impl_codec_for_numeric!(isize => i64);
impl_bitfield_for_numeric!(isize => i64);
impl_codec_for_numeric!(NonZeroIsize: isize? => i64);
impl_bitfield_for_numeric!(NonZeroIsize: isize? => i64);
}