linearize/impls/
enums.rs

1macro_rules! impl_enum {
2    ($ty:ty, $num:literal: $($name:ident => $idx:expr,)*) => {
3        // SAFETY: The tests below test all conditions.
4        unsafe impl crate::Linearize for $ty {
5            type Storage<T> = [T; Self::LENGTH];
6            type CopyStorage<T>
7                = [T; Self::LENGTH]
8            where
9                T: Copy;
10            const LENGTH: usize = $num;
11
12            #[inline]
13            fn linearize(&self) -> usize {
14                match self {
15                    $(<$ty>::$name => $idx,)*
16                }
17            }
18
19            #[inline]
20            unsafe fn from_linear_unchecked(linear: usize) -> Self
21            where
22                Self: Sized,
23            {
24                match linear {
25                    $($idx => <$ty>::$name,)*
26                    _ => unsafe {
27                        // SAFETY: It's a precondition that linear < Self::LENGTH,
28                        cold_unreachable!();
29                    },
30                }
31            }
32        }
33
34        impl_assert!($ty, $num);
35
36        #[test]
37        fn test() {
38            use crate::Linearize;
39            $(
40                assert_roundtrip!(<$ty>::$name, $idx);
41            )*
42            let variants = [$(<$ty>::$name),*];
43            assert_eq!(variants.len(), $num);
44            for (idx, variant) in variants.into_iter().enumerate() {
45                assert_eq!(variant.linearize(), idx);
46            }
47        }
48    };
49}
50
51mod core {
52    mod cmp {
53        mod ordering {
54            impl_enum! {
55                core::cmp::Ordering, 3:
56                Less => 0,
57                Equal => 1,
58                Greater => 2,
59            }
60        }
61    }
62
63    mod fmt {
64        mod alignment {
65            impl_enum! {
66                core::fmt::Alignment, 3:
67                Left => 0,
68                Right => 1,
69                Center => 2,
70            }
71        }
72    }
73
74    mod num {
75        mod fp_category {
76            impl_enum! {
77                core::num::FpCategory, 5:
78                Nan => 0,
79                Infinite => 1,
80                Zero => 2,
81                Subnormal => 3,
82                Normal => 4,
83            }
84        }
85    }
86}
87
88#[cfg(feature = "std")]
89mod std {
90    mod net {
91        mod shutdown {
92            impl_enum! {
93                std::net::Shutdown, 3:
94                Read => 0,
95                Write => 1,
96                Both => 2,
97            }
98        }
99    }
100}