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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//! This library provides useful derive macros intended for enums.
//!
//! The main point of that is to reduce boilerplate code and add useful shortcuts.
extern crate convert_case;
extern crate proc_macro;
extern crate proc_macro2;
extern crate quote;
extern crate syn;
use crate::;
/// This derive macro adds matching functions for each of your enum's variants.
///
/// These functions have the signature `pub fn am_{enum_variant}(&self) -> bool` where `{enum_variant}` is to be replaced by each variant's name in `snake_case`.
/// The conversion to `snake_case` is done by the [`convert_case`] crate.
///
/// # Example
///
/// ```rust
/// use derivenum::EnumMatch;
///
/// #[derive(EnumMatch)]
/// enum MyEnum {
/// FirstVariant(Vec<i32>),
/// SecondVariant {
/// field: String,
/// },
/// ThirdVariant
/// }
///
/// let enum_variant = MyEnum::FirstVariant(vec![1, 2, 3]);
/// assert!(enum_variant.am_first_variant());
/// assert!(!enum_variant.am_second_variant());
/// assert!(!enum_variant.am_third_variant());
///
/// let enum_variant = MyEnum::SecondVariant {
/// field: String::from("123"),
/// };
/// assert!(!enum_variant.am_first_variant());
/// assert!(enum_variant.am_second_variant());
/// assert!(!enum_variant.am_third_variant());
///
/// let enum_variant = MyEnum::ThirdVariant;
/// assert!(!enum_variant.am_first_variant());
/// assert!(!enum_variant.am_second_variant());
/// assert!(enum_variant.am_third_variant());
/// ```
///
/// Add the arrtibute `#[enum_match(ignore)]` to any variant to skip adding a `am_...()` function:
///
/// ```rust,compile_fail
/// use derivenum::EnumMatch;
///
/// #[derive(EnumMatch)]
/// enum MyEnum {
/// #[enum_match(ignore)]
/// SkippedVariant(i32),
/// }
///
/// let variant = MyEnum::SkippedVariant(1);
/// // this should not compile, because the function does not exist:
/// assert!(variant.am_skipped_variant());
/// ```
/// This derive macro adds take functions to your enum's variants to take the inner values out.
///
/// These functions have the signature `pub fn take_{enum_variant}(self) -> {return_type}` where `{enum_variant}` is to be replaced by the each unnamed enum variant in `snake_case`.
/// The conversion to `snake_case` is done by the [`convert_case`] crate.
/// In case the enum variant is a single unnamed one, `{return_type}` is to be replaced by the type inside the variant.
/// If the enum variant is unnamed, but has multiple fields, `{return_type}` is to be replaced by a tuple holding all types of the variant.
///
/// Named and Unit enum variants are skipped.
///
/// # Example
///
/// ```rust
/// use derivenum::EnumTake;
///
/// #[derive(EnumTake)]
/// enum MyEnum {
/// FirstVariant(Vec<i32>),
/// SecondVariant(u32, Vec<u32>, String),
/// // named variant is skipped
/// ThirdVariant {
/// field: String,
/// },
/// // unit variant is skipped
/// FourthVariant
/// }
///
/// let enum_variant = MyEnum::FirstVariant(vec![1, 2, 3]);
/// assert_eq!(enum_variant.take_first_variant(), vec![1, 2, 3]);
/// let enum_variant = MyEnum::SecondVariant(1, vec![1, 2, 3], String::from("alice"));
/// // note the tuple that encloses all types
/// assert_eq!(enum_variant.take_second_variant(), (1, vec![1, 2, 3], String::from("alice")));
/// ```
///
/// Add the arrtibute `#[enum_take(ignore)]` to any variant to skip adding a `take_...()` function:
///
/// ```rust,compile_fail
/// use derivenum::EnumTake;
///
/// #[derive(EnumTake)]
/// enum MyEnum {
/// #[enum_take(ignore)]
/// SkippedVariant(i32),
/// }
///
/// let variant = MyEnum::SkippedVariant(1);
/// // this should not compile, because the function does not exist:
/// let value = variant.take_skipped_variant();
/// ```