musli_zerocopy/pointer/
size.rs1use core::fmt;
2
3use crate::endian::ByteOrder;
4use crate::error::IntoRepr;
5use crate::traits::ZeroCopy;
6
7pub type DefaultSize = u32;
9
10#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64",)))]
11compile_error!("musli-zerocopy is only supported on 32, 64-bit platforms");
12
13mod sealed {
14 pub trait Sealed {}
15 impl Sealed for u8 {}
16 impl Sealed for u16 {}
17 impl Sealed for u32 {}
18 #[cfg(target_pointer_width = "64")]
19 impl Sealed for u64 {}
20 impl Sealed for usize {}
21}
22
23pub trait Size:
35 'static
36 + Sized
37 + TryFrom<usize>
38 + Copy
39 + fmt::Display
40 + fmt::Debug
41 + ZeroCopy
42 + IntoRepr
43 + self::sealed::Sealed
44{
45 #[doc(hidden)]
47 const ZERO: Self;
48
49 #[doc(hidden)]
51 const MAX: Self;
52
53 #[doc(hidden)]
54 const ONE: Self;
55
56 #[doc(hidden)]
57 const N2: Self;
58
59 #[doc(hidden)]
60 const N4: Self;
61
62 #[doc(hidden)]
63 const N8: Self;
64
65 #[doc(hidden)]
66 const N16: Self;
67
68 #[doc(hidden)]
69 fn wrapping_mul(self, other: Self) -> Self;
71
72 #[doc(hidden)]
73 fn checked_mul(self, other: Self) -> Option<Self>;
75
76 fn try_from_usize(value: usize) -> Option<Self>;
78
79 #[doc(hidden)]
81 fn as_usize<E>(self) -> usize
82 where
83 E: ByteOrder;
84
85 #[doc(hidden)]
87 fn is_zero(self) -> bool;
88}
89
90macro_rules! impl_size {
91 ($ty:ty, $swap:path) => {
92 #[doc = concat!("Size implementation for `", stringify!($ty), "`")]
93 #[doc = concat!("let max = ", stringify!($ty), "::MAX.as_usize::<endian::Big>();")]
100 #[doc = concat!("let min = ", stringify!($ty), "::MIN.as_usize::<endian::Little>();")]
101 impl Size for $ty {
103 const ZERO: Self = 0;
104 const MAX: Self = <$ty>::MAX;
105 const ONE: Self = 1;
106 const N2: Self = 2;
107 const N4: Self = 4;
108 const N8: Self = 8;
109 const N16: Self = 16;
110
111 #[inline(always)]
112 fn wrapping_mul(self, other: Self) -> Self {
113 self.wrapping_mul(other)
114 }
115
116 #[inline(always)]
117 fn checked_mul(self, other: Self) -> Option<Self> {
118 self.checked_mul(other)
119 }
120
121 #[inline]
122 fn try_from_usize(value: usize) -> Option<Self> {
123 if value > <$ty>::MAX as usize {
124 None
125 } else {
126 Some(value as $ty)
127 }
128 }
129
130 #[inline]
131 fn as_usize<E>(self) -> usize
132 where
133 E: ByteOrder,
134 {
135 if self > usize::MAX as $ty {
136 usize::MAX
137 } else {
138 $swap(self) as usize
139 }
140 }
141
142 #[inline]
143 fn is_zero(self) -> bool {
144 self == 0
145 }
146 }
147 };
148}
149
150impl_size!(u8, core::convert::identity);
151impl_size!(u16, E::swap_u16);
152impl_size!(u32, E::swap_u32);
153#[cfg(target_pointer_width = "64")]
154impl_size!(u64, E::swap_u64);
155impl_size!(usize, core::convert::identity);