use core::fmt;
use crate::endian::ByteOrder;
use crate::error::IntoRepr;
use crate::traits::ZeroCopy;
pub type DefaultSize = u32;
#[cfg(not(any(
target_pointer_width = "32",
target_pointer_width = "64",
target_pointer_width = "128"
)))]
compile_error!("musli-zerocopy is only supported on 32, 64, or 128-bit platforms");
mod sealed {
pub trait Sealed {}
impl Sealed for u8 {}
impl Sealed for u16 {}
impl Sealed for u32 {}
#[cfg(any(target_pointer_width = "64", target_pointer_width = "128"))]
impl Sealed for u64 {}
impl Sealed for usize {}
}
pub trait Size:
'static
+ Sized
+ TryFrom<usize>
+ Copy
+ fmt::Display
+ fmt::Debug
+ ZeroCopy
+ IntoRepr
+ self::sealed::Sealed
{
#[doc(hidden)]
const ZERO: Self;
#[doc(hidden)]
const MAX: Self;
#[doc(hidden)]
const ONE: Self;
#[doc(hidden)]
const N2: Self;
#[doc(hidden)]
const N4: Self;
#[doc(hidden)]
const N8: Self;
#[doc(hidden)]
const N16: Self;
#[doc(hidden)]
fn wrapping_mul(self, other: Self) -> Self;
#[doc(hidden)]
fn checked_mul(self, other: Self) -> Option<Self>;
fn try_from_usize(value: usize) -> Option<Self>;
#[doc(hidden)]
fn as_usize<E: ByteOrder>(self) -> usize;
#[doc(hidden)]
fn is_zero(self) -> bool;
}
macro_rules! impl_size {
($ty:ty, $swap:path) => {
#[doc = concat!("Size implementation for `", stringify!($ty), "`")]
#[doc = concat!("let max = ", stringify!($ty), "::MAX.as_usize::<endian::Big>();")]
#[doc = concat!("let min = ", stringify!($ty), "::MIN.as_usize::<endian::Little>();")]
impl Size for $ty {
const ZERO: Self = 0;
const MAX: Self = <$ty>::MAX;
const ONE: Self = 1;
const N2: Self = 2;
const N4: Self = 4;
const N8: Self = 8;
const N16: Self = 16;
#[inline(always)]
fn wrapping_mul(self, other: Self) -> Self {
self.wrapping_mul(other)
}
#[inline(always)]
fn checked_mul(self, other: Self) -> Option<Self> {
self.checked_mul(other)
}
#[inline]
fn try_from_usize(value: usize) -> Option<Self> {
if value > <$ty>::MAX as usize {
None
} else {
Some(value as $ty)
}
}
#[inline]
fn as_usize<E: ByteOrder>(self) -> usize {
if self > usize::MAX as $ty {
usize::MAX
} else {
$swap(self) as usize
}
}
#[inline]
fn is_zero(self) -> bool {
self == 0
}
}
};
}
impl_size!(u8, core::convert::identity);
impl_size!(u16, E::swap_u16);
impl_size!(u32, E::swap_u32);
#[cfg(any(target_pointer_width = "64", target_pointer_width = "128"))]
impl_size!(u64, E::swap_u64);
impl_size!(usize, core::convert::identity);