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}