Skip to content

Instantly share code, notes, and snippets.

@luser
Forked from anonymous/playground.rs
Last active June 10, 2016 15:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save luser/25bd25c12c15f282fd666baefab1dce4 to your computer and use it in GitHub Desktop.
Save luser/25bd25c12c15f282fd666baefab1dce4 to your computer and use it in GitHub Desktop.
Rust enum with attached strings
use std::slice::Iter;
use std::collections::HashSet;
trait EnumValues : Sized {
fn values() -> Iter<'static, Self>;
}
macro_rules! simple_enum {
($name:ident { $(($item:ident, $repr:expr),)* }) => {
#[derive(Debug)]
enum $name {
$(
$item,
)*
}
use std::fmt;
impl fmt::Display for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", match self {
$(
&$name::$item => $repr,
)*
})
}
}
use std::str::FromStr;
impl FromStr for $name {
type Err = ();
fn from_str(s: &str) -> Result<$name, ()> {
match s {
$(
$repr => Ok($name::$item),
)*
_ => Err(()),
}
}
}
impl EnumValues for $name {
fn values() -> Iter<'static, $name> {
static VALUES: &'static [$name] = &[$($name::$item),*];
VALUES.into_iter()
}
}
}
}
simple_enum!{
Foo {
(A, "a"),
(B, "b"),
}
}
fn main() {
let s = Foo::values().map(|v| v.to_string()).collect::<HashSet<String>>();
for v in Foo::values() {
println!("{} ({:?}): {}", v, v, s.contains(&v.to_string()));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment