Derive Macro EnumStringify

Source
#[derive(EnumStringify)]
{
    // Attributes available to this derive:
    #[enum_stringify]
}
Expand description

Derive std::fmt::Display, std::str::FromStr, TryFrom<&str> and TryFrom<String> for an enum.

They simply take the name of the enum variant and convert it to a string.

§Example

use enum_stringify::EnumStringify;
use std::str::FromStr;

#[derive(EnumStringify, Debug, PartialEq)]
enum Numbers {
   One,
   Two,
}

assert_eq!(Numbers::One.to_string(), "One");
assert_eq!(Numbers::Two.to_string(), "Two");


assert_eq!(Numbers::try_from("One").unwrap(), Numbers::One);
assert_eq!(Numbers::try_from("Two").unwrap(), Numbers::Two);

assert!(Numbers::try_from("Three").is_err());

§Prefix and suffix

You can add a prefix and/or a suffix to the string representation of the enum variants.

use enum_stringify::EnumStringify;
use std::str::FromStr;

#[derive(EnumStringify, Debug, PartialEq)]
#[enum_stringify(prefix = "MyPrefix", suffix = "MySuffix")]
enum Numbers {
  One,
  Two,
}

assert_eq!(Numbers::One.to_string(), "MyPrefixOneMySuffix");
assert_eq!(Numbers::Two.to_string(), "MyPrefixTwoMySuffix");

assert_eq!(Numbers::try_from("MyPrefixOneMySuffix").unwrap(), Numbers::One);
assert_eq!(Numbers::try_from("MyPrefixTwoMySuffix").unwrap(), Numbers::Two);

§Case

You can also set the case of the string representation of the enum variants. Case conversion is provided by the convert_case crate. Refer to the variants of the convert_case::Case enum for options (expressed in lower snake case). The exception are the Random and PseudoRandom variants, which are not accepted.

use enum_stringify::EnumStringify;
use std::str::FromStr;

#[derive(EnumStringify, Debug, PartialEq)]
#[enum_stringify(case = "lower")]
enum Numbers {
 One,
 Two,
}

assert_eq!(Numbers::One.to_string(), "one");
assert_eq!(Numbers::Two.to_string(), "two");

assert_eq!(Numbers::try_from("one").unwrap(), Numbers::One);
assert_eq!(Numbers::try_from("two").unwrap(), Numbers::Two);

§Rename variants

You can rename the variants of the enum. This is useful if you want to have a different name for the enum variants and the string representation of the enum variants.

use enum_stringify::EnumStringify;
use std::str::FromStr;

#[derive(EnumStringify, Debug, PartialEq)]
enum Istari {
 #[enum_stringify(rename = "Ólorin")]
 Gandalf,
 Saruman,
 Radagast,
 Alatar,
 Pallando,
}

assert_eq!(Istari::Gandalf.to_string(), "Ólorin");
assert_eq!(Istari::Saruman.to_string(), "Saruman");
assert_eq!(Istari::Radagast.to_string(), "Radagast");

assert_eq!(Istari::try_from("Ólorin").unwrap(), Istari::Gandalf);
assert_eq!(Istari::try_from("Saruman").unwrap(), Istari::Saruman);
assert_eq!(Istari::try_from("Radagast").unwrap(), Istari::Radagast);

§Details

The implementations of the above traits corresponds to this:

enum Numbers {
  One,
  Two,
}

impl ::std::fmt::Display for Numbers {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self {
            Self::One => write!(f, "One"),
            Self::Two => write!(f, "Two"),
        }
    }
}

impl TryFrom<&str> for Numbers {
    type Error = String;

    fn try_from(s: &str) -> Result<Self, Self::Error> {
        match s {    
            "One" => Ok(Self::One),
            "Two" => Ok(Self::Two),
            _ => {
                let mut err_msg = "Failed parse string ".to_string();
                err_msg.push_str(s);
                err_msg.push_str(" for enum ");
                err_msg.push_str("Numbers");
                Err(err_msg)
            }
        }
    }
}

impl TryFrom<String> for Numbers {
    type Error = String;
         
    fn try_from(s: String) -> Result<Self, Self::Error> {
        s.as_str().try_into()
    }
}

impl ::std::str::FromStr for Numbers {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        s.try_into()
    }
}