enum_table/
macros.rs

1/// A macro to create an `EnumTable` for a given enumeration and value type.
2///
3/// # Arguments
4///
5/// * `$variant` - The enumeration type that implements the `Enumable` trait.
6/// * `$value` - The type of values to be associated with each enumeration variant.
7/// * `$count` - The number of variants in the enumeration.
8/// * `$variable` - The variable name to use in the closure for each variant.
9/// * `$($tt:tt)*` - The closure that maps each variant to a value.
10///
11/// # Example
12///
13/// ```rust
14/// use enum_table::{EnumTable, Enumable, et};
15///
16/// #[derive(Copy, Clone)]
17/// enum Test {
18///     A,
19///     B,
20///     C,
21/// }
22///
23/// impl enum_table::Enumable for Test {
24///     const VARIANTS: &'static [Self] = &[Test::A, Test::B, Test::C];
25/// }
26///
27/// const TABLE: EnumTable<Test, &'static str, { Test::COUNT }> =
28///     et!(Test, &'static str, |t| match t {
29///         Test::A => "A",
30///         Test::B => "B",
31///         Test::C => "C",
32///     });
33///
34/// assert_eq!(TABLE.get(&Test::A), &"A");
35/// assert_eq!(TABLE.get(&Test::B), &"B");
36/// assert_eq!(TABLE.get(&Test::C), &"C");
37///
38#[macro_export]
39macro_rules! et {
40    ($variant:ty, $value:ty, $COUNT:block, |$variable:ident| $($tt:tt)*) => {
41        {
42            let mut builder = $crate::builder::EnumTableBuilder::<$variant, $value, $COUNT>::new();
43
44            let mut i = 0;
45            while i < builder.capacity() {
46                let $variable = &<$variant as $crate::Enumable>::VARIANTS[i];
47                let value = $($tt)*;
48                let t = $variable;
49                unsafe {
50                    builder.push_unchecked(
51                        t,
52                        value,
53                    );
54                }
55                i += 1;
56            }
57
58            unsafe { builder.build_to_unchecked() }
59        }
60    };
61    ($variant:ty, $value:ty, |$variable:ident| $($tt:tt)*) => {
62        $crate::et!($variant, $value, { <$variant as $crate::Enumable>::COUNT }, |$variable| $($tt)*)
63    };
64}
65
66#[cfg(test)]
67mod tests {
68    use crate::{EnumTable, Enumable};
69
70    #[test]
71    fn et_macro() {
72        #[derive(Clone, Copy, Enumable)]
73        enum Test {
74            A,
75            B,
76            C,
77        }
78
79        const TABLE: EnumTable<Test, &'static str, { Test::COUNT }> =
80            et!(Test, &'static str, |t| match t {
81                Test::A => "A",
82                Test::B => "B",
83                Test::C => "C",
84            });
85
86        assert_eq!(TABLE.get(&Test::A), &"A");
87        assert_eq!(TABLE.get(&Test::B), &"B");
88        assert_eq!(TABLE.get(&Test::C), &"C");
89    }
90}