enum_str/lib.rs
1/*!
2This crate provides a macro to create a unitary enum and conversions from enum variants to a string
3representation and vice versa.
4
5# Why another crate?
6The string representation does not need to be the same as the enum variant's identifier. See the
7example below for clarification.
8
9# Example
10```rust
11#[macro_use] extern crate enum_str;
12
13use std::str::FromStr;
14use enum_str::{Error, AsStr};
15
16fn main() {
17 enum_str! {
18 Fruit,
19 (Apple, "🍎"),
20 (Pineapple, "🍍"),
21 (Strawberry, "🍓"),
22 }
23 assert_eq!("🍎", Fruit::Apple.as_str());
24 assert_eq!(Fruit::Apple, Fruit::from_str("🍎").unwrap());
25}
26```
27*/
28extern crate failure;
29
30#[macro_use]
31extern crate failure_derive;
32
33/// Defines errors for this module
34#[derive(Debug, Fail)]
35pub enum Error {
36 /// Failure to parse string used in `FromStr` trait
37 #[fail(display = "failed to parse '{}' to {}", input, to)]
38 ParseStrError {
39 /// string we are trying to convert
40 input: String,
41 /// name of the enum we are converting to
42 to: String,
43 }
44}
45
46/// Trait for representing a structure as a string
47pub trait AsStr {
48 /// Get the string representation of a structure
49 fn as_str(&self) -> &str;
50}
51
52/**
53Macro used to generate an enum with `FromStr` and `AsStr` trait implementations.
54
55The enum is identified by the `name` passed to the macro. Enum values are identified by
56the `key` passed in each tuple. The 'value' is used as the string representation for
57FromStr and AsStr traits.
58
59See crate [Example](index.html#example) for usage.
60*/
61#[macro_export]
62macro_rules! enum_str {
63 ($name:ident, $(($key:ident, $value:expr),)*) => {
64 #[derive(Debug, PartialEq)]
65 enum $name
66 {
67 $($key),*
68 }
69
70 impl AsStr for $name {
71 fn as_str(&self) -> &str {
72 match self {
73 $(
74 &$name::$key => $value
75 ),*
76 }
77 }
78 }
79
80 impl FromStr for $name {
81 type Err = Error;
82
83 fn from_str(val: &str) -> Result<Self, Self::Err> {
84 match val
85 {
86 $(
87 $value => Ok($name::$key)
88 ),*,
89 _ => Err(Error::ParseStrError{input: val.to_string(), to: stringify!($name).to_string()})
90 }
91 }
92 }
93 }
94}