musli_zerocopy/pointer/
size.rs1use crate::error::{CoerceError, CoerceErrorKind};
2use crate::traits::ZeroCopy;
3
4pub type DefaultSize = u32;
6
7#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
8compile_error!("musli-zerocopy is only supported on 32, 64-bit platforms");
9
10mod sealed {
11 pub trait Sealed {}
12 impl Sealed for u8 {}
13 impl Sealed for u16 {}
14 #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
15 impl Sealed for u32 {}
16 #[cfg(target_pointer_width = "64")]
17 impl Sealed for u64 {}
18 impl Sealed for usize {}
19}
20
21pub trait Size
33where
34 Self: 'static + Copy + ZeroCopy + self::sealed::Sealed,
35{
36 #[doc(hidden)]
38 const ZERO: Self;
39
40 #[doc(hidden)]
42 const MAX: Self;
43
44 #[doc(hidden)]
46 const MAX_USIZE: usize;
47
48 #[doc(hidden)]
49 const ONE: Self;
50
51 #[doc(hidden)]
52 const N2: Self;
53
54 #[doc(hidden)]
55 const N4: Self;
56
57 #[doc(hidden)]
58 const N8: Self;
59
60 #[doc(hidden)]
61 const N16: Self;
62
63 #[inline(always)]
65 fn try_from<U>(other: U) -> Result<Self, CoerceError>
66 where
67 U: Size,
68 {
69 Self::try_from_usize(other.as_usize())
70 }
71
72 #[doc(hidden)]
73 fn wrapping_mul(self, other: Self) -> Self;
75
76 #[doc(hidden)]
77 fn checked_mul(self, other: Self) -> Option<Self>;
79
80 fn try_from_usize(value: usize) -> Result<Self, CoerceError>;
82
83 #[doc(hidden)]
85 fn as_usize(self) -> usize;
86
87 #[doc(hidden)]
89 fn is_zero(self) -> bool;
90}
91
92macro_rules! impl_size {
93 ($ty:ty) => {
94 #[doc = concat!("Size implementation for `", stringify!($ty), "`")]
95 #[doc = concat!("let max = ", stringify!($ty), "::MAX;")]
102 impl Size for $ty {
104 const ZERO: Self = 0;
105 const MAX: Self = <$ty>::MAX;
106 const MAX_USIZE: usize = <$ty>::MAX as usize;
107 const ONE: Self = 1;
108 const N2: Self = 2;
109 const N4: Self = 4;
110 const N8: Self = 8;
111 const N16: Self = 16;
112
113 #[inline(always)]
114 fn wrapping_mul(self, other: Self) -> Self {
115 self.wrapping_mul(other)
116 }
117
118 #[inline(always)]
119 fn checked_mul(self, other: Self) -> Option<Self> {
120 self.checked_mul(other)
121 }
122
123 #[inline]
124 fn try_from_usize(value: usize) -> Result<Self, CoerceError> {
125 if value > <$ty>::MAX as usize {
126 Err(CoerceError::new(CoerceErrorKind::LengthOverflow {
127 len: value,
128 size: <$ty>::MAX as usize,
129 }))
130 } else {
131 Ok(value as $ty)
132 }
133 }
134
135 #[inline]
136 fn as_usize(self) -> usize {
137 debug_assert!(
138 <usize as TryFrom<_>>::try_from(self).is_ok(),
139 "Value {self} cannot be represented on this platform"
140 );
141 self as usize
142 }
143
144 #[inline]
145 fn is_zero(self) -> bool {
146 self == 0
147 }
148 }
149 };
150}
151
152impl_size!(u8);
153impl_size!(u16);
154#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
155impl_size!(u32);
156#[cfg(target_pointer_width = "64")]
157impl_size!(u64);
158impl_size!(usize);