use std::{error::Error as StdError, fmt};
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct ParseEnumError {
pub enum_name: &'static str,
}
impl fmt::Display for ParseEnumError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "invalid {} variant", self.enum_name)
}
}
impl StdError for ParseEnumError {}
#[macro_export]
macro_rules! enum_string {
(
$(#[$meta:meta])*
$vis:vis enum $name:ident {
$(
$(#[$variant_meta:meta])*
$variant:ident $(= $value:expr)?
),* $(,)?
}
) => {
$(#[$meta])*
$vis enum $name {
$(
$(#[$variant_meta])*
$variant $(= $value)?
),*
}
impl $name {
#[inline]
pub const fn as_str(&self) -> &'static str {
match self {
$(
Self::$variant => ::core::stringify!($variant),
)*
}
}
}
impl ::core::fmt::Display for $name {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
f.write_str(self.as_str())
}
}
impl ::core::str::FromStr for $name {
type Err = $crate::ParseEnumError;
fn from_str(s: &str) -> ::core::result::Result<Self, Self::Err> {
match s {
$(
::core::stringify!($variant) => ::core::result::Result::Ok(Self::$variant),
)*
_ => ::core::result::Result::Err($crate::ParseEnumError {
enum_name: ::core::stringify!($name),
}),
}
}
}
};
(
$(#[$meta:meta])*
$vis:vis enum $name:ident < $($tt:tt)*
) => {
compile_error!("enum_string! does not support generic parameters");
};
}