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: usize;
43
44 #[doc(hidden)]
45 const ONE: Self;
46
47 #[doc(hidden)]
48 const N2: Self;
49
50 #[doc(hidden)]
51 const N4: Self;
52
53 #[doc(hidden)]
54 const N8: Self;
55
56 #[doc(hidden)]
57 const N16: Self;
58
59 #[doc(hidden)]
60 fn eq(self, other: Self) -> bool;
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 #[doc(hidden)]
81 fn checked_add(self, other: Self) -> Option<Self>;
83
84 #[doc(hidden)]
85 fn checked_sub(self, other: Self) -> Option<Self>;
87
88 fn from_usize(value: usize) -> Self;
90
91 fn try_from_usize(value: usize) -> Result<Self, CoerceError>;
93
94 #[doc(hidden)]
96 fn as_usize(self) -> usize;
97
98 #[doc(hidden)]
100 fn is_zero(self) -> bool;
101}
102
103macro_rules! impl_size {
104 ($ty:ty) => {
105 #[doc = concat!("Size implementation for `", stringify!($ty), "`")]
106 #[doc = concat!("let max = ", stringify!($ty), "::MAX;")]
113 impl Size for $ty {
115 const ZERO: Self = 0;
116 const MAX: usize = <$ty>::MAX as usize;
117 const ONE: Self = 1;
118 const N2: Self = 2;
119 const N4: Self = 4;
120 const N8: Self = 8;
121 const N16: Self = 16;
122
123 #[inline(always)]
124 fn eq(self, other: Self) -> bool {
125 self == other
126 }
127
128 #[inline(always)]
129 fn wrapping_mul(self, other: Self) -> Self {
130 self.wrapping_mul(other)
131 }
132
133 #[inline(always)]
134 fn checked_mul(self, other: Self) -> Option<Self> {
135 self.checked_mul(other)
136 }
137
138 #[inline(always)]
139 fn checked_add(self, other: Self) -> Option<Self> {
140 self.checked_add(other)
141 }
142
143 #[inline(always)]
144 fn checked_sub(self, other: Self) -> Option<Self> {
145 self.checked_sub(other)
146 }
147
148 #[inline(always)]
149 fn from_usize(value: usize) -> Self {
150 debug_assert!(
151 value <= <$ty>::MAX as usize,
152 "Value {value} cannot be represented on this platform"
153 );
154 value as $ty
155 }
156
157 #[inline(always)]
158 fn try_from_usize(value: usize) -> Result<Self, CoerceError> {
159 if value > <$ty>::MAX as usize {
160 Err(CoerceError::new(CoerceErrorKind::LengthOverflow {
161 len: value,
162 size: <$ty>::MAX as usize,
163 }))
164 } else {
165 Ok(value as $ty)
166 }
167 }
168
169 #[inline(always)]
170 fn as_usize(self) -> usize {
171 debug_assert!(
172 <usize as TryFrom<_>>::try_from(self).is_ok(),
173 "Value {self} cannot be represented on this platform"
174 );
175 self as usize
176 }
177
178 #[inline(always)]
179 fn is_zero(self) -> bool {
180 self == 0
181 }
182 }
183 };
184}
185
186impl_size!(u8);
187impl_size!(u16);
188#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
189impl_size!(u32);
190#[cfg(target_pointer_width = "64")]
191impl_size!(u64);
192impl_size!(usize);