named.rs

1.5 kB · rust · 47 lines

1macro_rules! named_enum {2    (3        $(#[$enum_meta:meta])*4        pub enum $name:ident {5            $($(#[$variant_meta:meta])* $variant:ident => $word:literal,)+6        }7    ) => {8        $(#[$enum_meta])*9        pub enum $name {10            $($(#[$variant_meta])* $variant,)+11        }1213        impl $name {14            #[doc = concat!("Returns every ", stringify!($name), " in canonical order.")]15            pub const fn all() -> [$name; [$($name::$variant),+].len()] {16                [$($name::$variant),+]17            }18            #[doc = concat!("Returns the ", stringify!($name), "'s display name.")]19            pub fn name(&self) -> &'static str {20                match self {21                    $($name::$variant => $word,)+22                }23            }24        }2526        impl ::std::fmt::Display for $name {27            fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {28                f.write_str(self.name())29            }30        }3132        impl ::std::str::FromStr for $name {33            type Err = $crate::core::error::Error;34            fn from_str(word: &str) -> ::std::result::Result<$name, Self::Err> {35                match word {36                    $($word => Ok($name::$variant),)+37                    other => Err($crate::core::error::Error::Value(format!(38                        "unknown {} {other:?}.",39                        stringify!($name).to_lowercase()40                    ))),41                }42            }43        }44    };45}4647pub(crate) use named_enum;