Skip to main content

enum_table/
macros.rs

1/// Builds an `EnumTable` for `$variant` and `$value` inside a `const` block.
2///
3/// The closure body must be valid in a `const` context; passing a non-`const`
4/// expression is a compile error. For a runtime equivalent, use
5/// [`crate::EnumTable::from_fn`], [`crate::EnumTable::try_from_fn`], or
6/// [`crate::EnumTable::checked_from_fn`] instead.
7///
8/// # Examples
9///
10/// ```rust
11/// use enum_table::{EnumTable, Enumerable, et};
12///
13/// #[derive(Enumerable, Copy, Clone)]
14/// enum Test {
15///     A,
16///     B,
17///     C,
18/// }
19///
20/// const TABLE: EnumTable<Test, &'static str, { Test::COUNT }> =
21///     et!(Test, &'static str, |t| match t {
22///         Test::A => "A",
23///         Test::B => "B",
24///         Test::C => "C",
25///     });
26///
27/// assert_eq!(TABLE.get(Test::A), &"A");
28/// assert_eq!(TABLE.get(Test::B), &"B");
29/// assert_eq!(TABLE.get(Test::C), &"C");
30/// ```
31#[macro_export]
32macro_rules! et {
33    ($variant:ty, $value:ty, |$variable:ident| $($tt:tt)*) => {
34        const {
35            let mut builder = $crate::__private::EnumTableBuilder::<
36                $variant,
37                $value,
38                { <$variant as $crate::Enumerable>::COUNT },
39            >::new_uninit();
40
41            let mut i = 0;
42            while i < <$variant as $crate::Enumerable>::COUNT  {
43                let $variable = &<$variant as $crate::Enumerable>::VARIANTS[i];
44                let value = $($tt)*;
45                unsafe {
46                    builder.push_unchecked(i, value);
47                }
48                i += 1;
49            }
50
51            unsafe { builder.build_unchecked() }
52        }
53    };
54}