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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/*!
# enum-methods
[](https://travis-ci.org/alekratz/enum-methods)
[](https://crates.io/crates/enum-methods)
Enum getter/`is_*` method generation.
#### Please note that this crate is unstable and is subject to change frequently.
I will attempt to prevent *seriously* breaking changes after we hit 0.1.0.
# Links
* [Github](https://github.com/alekratz/enum-methods)
* [crates.io](https://crates.io/crates/enum-methods)
* [docs.rs](https://docs.rs/enum-methods/0.0.8/enum_methods/)
# Usage
In your `Cargo.toml`, add this line under your `[dependencies]` section:
```toml,no_run
enum-methods = "0.0.8"
```
To use, simply derive and call methods (see the example below).
# Why?
Usually when you write an enum with one or zero values, you might want to
add a set of getters for them. As such:
```rust
#[derive(Debug)]
enum MyEnum {
FooBarBaz(i64),
BazBarFoo(String),
// ... and others
}
impl MyEnum {
pub fn foo_bar_baz(&self) -> i64 {
if let &MyEnum::FooBarBaz(i) = self {
i
}
else {
panic!("called MyEnum::FooBarBaz() on {:?}", self)
}
}
// et cetera
}
```
But this gets tedious, and adds a lot code for this simple functionality.
Enter `enum-methods`.
Instead of doing the above with the `if let ... else { panic!(...) }`, you
simply derive from the `EnumIntoGetters`
```rust
#[macro_use]
extern crate enum_methods;
#[derive(EnumIntoGetters, EnumAsGetters, EnumIsA, Debug)]
enum MyEnum {
FooBarBaz(i64),
BazBarFoo(String),
// ... and others
}
fn main() {
let my_foo = MyEnum::FooBarBaz(42);
// EnumIsA - creates is_* methods for every member
if my_foo.is_foo_bar_baz() {
// EnumAsGetters - gets a reference to the enum, panicking if it is
// not the specified variant
assert_eq!(*my_foo.as_foo_bar_baz(), 42);
// EnumIntoGetters - consumes the enum, yielding its owned value,
// and panicking if it is not the specified variant
assert_eq!(my_foo.into_foo_bar_baz(), 42);
}
}
```
# Requirements and gotchas
Right now, `enum-methods` has four derivable options:
* `EnumAsGetters` for generating `as_*` methods, which return a reference.
* `EnumIntoGetters` for generating `into_*` methods, which consume the enum
and returns the data held by the variant.
* `EnumToGetters` for generating `to_*` methods, which returns a clone of
the data held by the variant.
* `EnumIsA` for generating `is_*` methods, which return a boolean indicating
whether the enum matches that variant.
`EnumAsGetters`, `EnumIntoGetters`, and `EnumToGetters` have some limitations.
* Any enum variant which has exactly 1 member will have a getter generated for
it. All other variants are ignored.
* Enums which derive from `EnumIntoGetters` must also derive from `Debug` - this
is for when a method is called for the wrong variant and needs to `panic!`.
Furthermore, `EnumToGetters` is *only* for enums whose variants implement
`Clone`. There is not yet support for th
`EnumIsA` is much simpler than the previous; it simply adds `is_*`
methods returning a boolean for whether the variant matches or not.
**For all generated methods, all names are automatically converted to
snake_case**.
# License
This software is released under the Apache license 2.0. See the LICENSE file
for more details.
*/
extern crate proc_macro;
extern crate quote;
extern crate syn;
use *;
use *;
use TokenStream;
use *;
// TODO : map types for what a reference should return in its getter
// e.g. String -> &str in the getter