Skip to main content

pumpkinplus/mirror_types/
macros.rs

1/// Generates a mirror enum with serde, Display, matches_config, and From impls.
2///
3/// # Usage
4/// ```
5/// mirror_enum! {
6///     pub enum GameMode from pumpkin_plugin_api::player::GameMode {
7///         Survival,
8///         Creative,
9///         Adventure,
10///         Spectator,
11///     }
12/// }
13/// ```
14///
15/// This produces:
16/// - An enum with `Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash`
17/// - `#[serde(rename_all = "PascalCase")]`
18/// - `matches_config(&self, allowed: &[Self]) -> bool`
19/// - `Display` via `Debug` representation
20/// - `From<upstream>` with a catch-all fallback to the first variant
21#[macro_export]
22macro_rules! mirror_enum {
23    (
24        $(#[$meta:meta])*
25        $vis:vis enum $name:ident from $upstream:path {
26            $first:ident,
27            $($variant:ident),* $(,)?
28        }
29    ) => {
30        $(#[$meta])*
31        #[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash)]
32        #[serde(rename_all = "PascalCase")]
33        $vis enum $name {
34            $first,
35            $($variant),*
36        }
37
38        impl $name {
39            /// Returns true if the given list is empty (allow-all) or contains this variant.
40            pub fn matches_config(&self, allowed: &[Self]) -> bool {
41                allowed.is_empty() || allowed.contains(self)
42            }
43        }
44
45        impl std::fmt::Display for $name {
46            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47                write!(f, "{:?}", self)
48            }
49        }
50
51        impl From<$upstream> for $name {
52            fn from(value: $upstream) -> Self {
53                #[allow(unreachable_patterns)]
54                match value {
55                    <$upstream>::$first => Self::$first,
56                    $(<$upstream>::$variant => Self::$variant,)*
57                    _ => Self::$first,
58                }
59            }
60        }
61    };
62}