1use core::cmp::Ordering;
4use core::fmt;
5
6macro_rules! impl_fmt {
8 ($ty:ty, $($trait:ident),*) => {
9 $(
10 impl fmt::$trait for $ty {
11 #[inline]
12 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13 self.get().fmt(f)
14 }
15 }
16 )*
17 };
18}
19
20macro_rules! define_type {
22 ($ty:ident, $backend:ty, $tyint:ident) => {
23 #[doc = concat!("`", stringify!($tyint), "`")]
24 #[doc = concat!(" `", stringify!($tyint), "::MAX`")]
26 #[doc = concat!("`Option<", stringify!($ty), ">`")]
29 #[doc = concat!("`", stringify!($ty), "`")]
31 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
33 #[repr(transparent)]
34 pub(crate) struct $ty($backend);
35
36 impl $ty {
37 #[doc = concat!("`", stringify!($tyint), "`")]
39 #[inline]
41 #[must_use]
42 pub(crate) fn new(n: usize) -> Option<Self> {
43 <$tyint>::try_from(n)
44 .ok()
45 .and_then(|n| <$backend>::new(!n))
46 .map(Self)
47 }
48
49 #[inline]
51 #[must_use]
52 pub(crate) const fn get(self) -> usize {
53 !self.0.get() as usize
56 }
57 }
58
59 impl Default for $ty {
60 fn default() -> Self {
61 Self::new(0).expect("[validity] 0 is not the max value of the internal integer")
62 }
63 }
64
65 impl Ord for $ty {
66 #[inline]
67 fn cmp(&self, other: &Self) -> Ordering {
68 self.0.cmp(&other.0).reverse()
69 }
70 }
71
72 impl PartialOrd for $ty {
73 #[inline]
74 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
75 Some(self.cmp(other))
76 }
77 }
78
79 impl_fmt!($ty, Debug, Display, Binary, Octal, LowerHex, UpperHex);
80 };
81}
82
83define_type!(NonMaxU8, core::num::NonZeroU8, u8);
84define_type!(NonMaxU16, core::num::NonZeroU16, u16);
85define_type!(NonMaxU32, core::num::NonZeroU32, u32);
86define_type!(NonMaxU64, core::num::NonZeroU64, u64);
87define_type!(NonMaxUsize, core::num::NonZeroUsize, usize);
88
89#[cfg(test)]
90mod tests {
91 use super::NonMaxUsize;
92
93 use core::mem::size_of;
94
95 #[test]
96 fn types_size() {
97 assert_eq!(
98 size_of::<NonMaxUsize>(),
99 size_of::<usize>(),
100 "`NonMaxUsize` should be same size as `usize`"
101 );
102 assert_eq!(
103 size_of::<Option<NonMaxUsize>>(),
104 size_of::<NonMaxUsize>(),
105 "`Option<NonMaxUsize>` should be same size as `NonMaxUsize`"
106 );
107 }
108}