1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//! Various macros providing more beautiful syntax for enums.

/// Macro providing a more beautiful syntax for enums.
/// 
/// # Examples
/// 
/// ```
/// use alt_enum::alt_enum;
/// 
/// alt_enum!(
/// #[derive(Debug)]
/// test enum:
///     first,
///     second-variant,
///     nyan nyan
/// );
/// 
/// assert_eq!(format!("{:?}", TestEnum::SecondVariant), "SecondVariant");
/// ```
#[macro_export]
macro_rules! alt_enum {
    (
        $(#[$attr:meta])*
        $vis:vis $($name:ident $(-)?)+:
            $($($variant:ident $(-)?)+),*
            $(,)?
    ) => {
        paste::paste! {
            $(#[$attr])*
            $vis enum [<$($name:camel) +>] {
                $([<$($variant:camel) +>]),*
            }
        }
    };
}

/// Macro providing a more beautiful syntax for enums with associated values.
/// 
/// (using value-enum crate, needs value_enum feature enabled)
/// 
/// # Examples
/// 
/// ```
/// use alt_enum::alt_val_enum;
/// 
/// alt_val_enum!(
/// #[derive(Debug)]
/// some nya -> &'static str:
///     first: "42",
///     second-variant: "meow",
///     nyan nyan: "nyaa~"
/// );
/// 
/// assert_eq!(<&str>::from(SomeNya::NyanNyan), "nyaa~");
/// ```
#[macro_export]
#[cfg(feature = "value_enum")]
macro_rules! alt_val_enum {
    (
        $(#[$attr:meta])*
        $vis:vis $($name:ident $(-)?)+ -> $type:ty:
            $($($variant:ident $(-)?)+: $value:literal),*
            $(,)?
    ) => {
        paste::paste! { value_enum::value_enum! { 
            $type =>
            $(#[$attr])*
            $vis enum [<$($name:camel)+>] {
                $([<$($variant:camel)+>] = $value),*
            }
        }}
    };
}

#[cfg(test)]
mod tests {
    use super::*;

    alt_enum!(
    #[derive(Debug)]
    test enm:
        test nya,
        second-variant,
    );

    #[test]
    fn test() {
        assert_eq!(format!("{:?}", TestEnm::TestNya), "TestNya");
        assert_eq!(format!("{:?}", TestEnm::SecondVariant), "SecondVariant");
    }
}

#[cfg(test)]
#[cfg(feature = "value_enum")]
mod val_tests {
    use super::*;

    alt_val_enum!(
    #[derive(Debug)]
    test enm -> &'static str:
        test nya: "nya",
        second-variant: "second",
    );

    #[test]
    fn test_val() {
        assert_eq!(<&str>::from(TestEnm::TestNya), "nya");
        assert_eq!(<&str>::from(TestEnm::SecondVariant), "second");
    }
}