1 //! # Strum
2 //!
3 //! Strum is a set of macros and traits for working with
4 //! enums and strings easier in Rust.
5 //!
6 //! # Documentation
7 //!
8 //! The documentation for this crate is found in the `strum` crate.
9 
10 #![recursion_limit = "128"]
11 
12 extern crate heck;
13 #[macro_use]
14 extern crate syn;
15 #[macro_use]
16 extern crate quote;
17 extern crate proc_macro;
18 extern crate proc_macro2;
19 
20 mod helpers;
21 mod macros;
22 
23 use proc_macro2::TokenStream;
24 use std::env;
25 
debug_print_generated(ast: &syn::DeriveInput, toks: &TokenStream)26 fn debug_print_generated(ast: &syn::DeriveInput, toks: &TokenStream) {
27     let debug = env::var("STRUM_DEBUG");
28     if let Ok(s) = debug {
29         if s == "1" {
30             println!("{}", toks);
31         }
32 
33         if ast.ident == s {
34             println!("{}", toks);
35         }
36     }
37 }
38 
39 #[cfg_attr(
40     not(feature = "verbose-enumstring-name"),
41     proc_macro_derive(EnumString, attributes(strum))
42 )]
43 #[cfg_attr(
44     feature = "verbose-enumstring-name",
45     proc_macro_derive(StrumEnumString, attributes(strum))
46 )]
from_string(input: proc_macro::TokenStream) -> proc_macro::TokenStream47 pub fn from_string(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
48     let ast = syn::parse(input).unwrap();
49 
50     let toks = macros::from_string::from_string_inner(&ast);
51     debug_print_generated(&ast, &toks);
52     toks.into()
53 }
54 
55 #[cfg_attr(
56     not(feature = "verbose-asrefstr-name"),
57     proc_macro_derive(AsRefStr, attributes(strum))
58 )]
59 #[cfg_attr(
60     feature = "verbose-asrefstr-name",
61     proc_macro_derive(StrumAsRefStr, attributes(strum))
62 )]
as_ref_str(input: proc_macro::TokenStream) -> proc_macro::TokenStream63 pub fn as_ref_str(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
64     let ast = syn::parse(input).unwrap();
65 
66     let toks = macros::as_ref_str::as_ref_str_inner(&ast);
67     debug_print_generated(&ast, &toks);
68     toks.into()
69 }
70 
71 #[cfg_attr(
72     not(feature = "verbose-variant-names"),
73     proc_macro_derive(EnumVariantNames, attributes(strum))
74 )]
75 #[cfg_attr(
76     feature = "verbose-variant-names",
77     proc_macro_derive(StrumEnumVariantNames, attributes(strum))
78 )]
variant_names(input: proc_macro::TokenStream) -> proc_macro::TokenStream79 pub fn variant_names(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
80     let ast = syn::parse(input).unwrap();
81 
82     let toks = macros::enum_variant_names::enum_variant_names_inner(&ast);
83     debug_print_generated(&ast, &toks);
84     toks.into()
85 }
86 
87 #[cfg_attr(
88     feature = "verbose-asstaticstr-name",
89     proc_macro_derive(StrumAsStaticStr, attributes(strum))
90 )]
91 #[cfg_attr(
92     not(feature = "verbose-asstaticstr-name"),
93     proc_macro_derive(AsStaticStr, attributes(strum))
94 )]
as_static_str(input: proc_macro::TokenStream) -> proc_macro::TokenStream95 pub fn as_static_str(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
96     let ast = syn::parse(input).unwrap();
97 
98     let toks = macros::as_ref_str::as_static_str_inner(
99         &ast,
100         macros::as_ref_str::GenerateTraitVariant::AsStaticStr,
101     );
102     debug_print_generated(&ast, &toks);
103     toks.into()
104 }
105 
106 #[cfg_attr(
107     feature = "verbose-intostaticstr-name",
108     proc_macro_derive(StrumIntoStaticStr, attributes(strum))
109 )]
110 #[cfg_attr(
111     not(feature = "verbose-intostaticstr-name"),
112     proc_macro_derive(IntoStaticStr, attributes(strum))
113 )]
into_static_str(input: proc_macro::TokenStream) -> proc_macro::TokenStream114 pub fn into_static_str(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
115     let ast = syn::parse(input).unwrap();
116 
117     let toks = macros::as_ref_str::as_static_str_inner(
118         &ast,
119         macros::as_ref_str::GenerateTraitVariant::From,
120     );
121     debug_print_generated(&ast, &toks);
122     toks.into()
123 }
124 
125 #[cfg_attr(
126     feature = "verbose-tostring-name",
127     proc_macro_derive(StrumToString, attributes(strum))
128 )]
129 #[cfg_attr(
130     not(feature = "verbose-tostring-name"),
131     proc_macro_derive(ToString, attributes(strum))
132 )]
to_string(input: proc_macro::TokenStream) -> proc_macro::TokenStream133 pub fn to_string(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
134     let ast = syn::parse(input).unwrap();
135 
136     let toks = macros::to_string::to_string_inner(&ast);
137     debug_print_generated(&ast, &toks);
138     toks.into()
139 }
140 
141 #[cfg_attr(
142     feature = "verbose-display-name",
143     proc_macro_derive(StrumDisplay, attributes(strum))
144 )]
145 #[cfg_attr(
146     not(feature = "verbose-display-name"),
147     proc_macro_derive(Display, attributes(strum))
148 )]
display(input: proc_macro::TokenStream) -> proc_macro::TokenStream149 pub fn display(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
150     let ast = syn::parse(input).unwrap();
151 
152     let toks = macros::display::display_inner(&ast);
153     debug_print_generated(&ast, &toks);
154     toks.into()
155 }
156 
157 #[cfg_attr(
158     feature = "verbose-enumiter-name",
159     proc_macro_derive(StrumEnumIter, attributes(strum))
160 )]
161 #[cfg_attr(
162     not(feature = "verbose-enumiter-name"),
163     proc_macro_derive(EnumIter, attributes(strum))
164 )]
enum_iter(input: proc_macro::TokenStream) -> proc_macro::TokenStream165 pub fn enum_iter(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
166     let ast = syn::parse(input).unwrap();
167 
168     let toks = macros::enum_iter::enum_iter_inner(&ast);
169     debug_print_generated(&ast, &toks);
170     toks.into()
171 }
172 
173 #[cfg_attr(
174     feature = "verbose-enummessage-name",
175     proc_macro_derive(StrumEnumMessage, attributes(strum))
176 )]
177 #[cfg_attr(
178     not(feature = "verbose-enummessage-name"),
179     proc_macro_derive(EnumMessage, attributes(strum))
180 )]
enum_messages(input: proc_macro::TokenStream) -> proc_macro::TokenStream181 pub fn enum_messages(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
182     let ast = syn::parse(input).unwrap();
183 
184     let toks = macros::enum_messages::enum_message_inner(&ast);
185     debug_print_generated(&ast, &toks);
186     toks.into()
187 }
188 
189 #[cfg_attr(
190     feature = "verbose-enumproperty-name",
191     proc_macro_derive(StrumEnumProperty, attributes(strum))
192 )]
193 #[cfg_attr(
194     not(feature = "verbose-enumproperty-name"),
195     proc_macro_derive(EnumProperty, attributes(strum))
196 )]
enum_properties(input: proc_macro::TokenStream) -> proc_macro::TokenStream197 pub fn enum_properties(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
198     let ast = syn::parse(input).unwrap();
199 
200     let toks = macros::enum_properties::enum_properties_inner(&ast);
201     debug_print_generated(&ast, &toks);
202     toks.into()
203 }
204 
205 #[cfg_attr(
206     feature = "verbose-enumdiscriminants-name",
207     proc_macro_derive(StrumEnumDiscriminants, attributes(strum, strum_discriminants))
208 )]
209 #[cfg_attr(
210     not(feature = "verbose-enumdiscriminants-name"),
211     proc_macro_derive(EnumDiscriminants, attributes(strum, strum_discriminants))
212 )]
enum_discriminants(input: proc_macro::TokenStream) -> proc_macro::TokenStream213 pub fn enum_discriminants(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
214     let ast = syn::parse(input).unwrap();
215 
216     let toks = macros::enum_discriminants::enum_discriminants_inner(&ast);
217     debug_print_generated(&ast, &toks);
218     toks.into()
219 }
220 
221 #[cfg_attr(
222     feature = "verbose-enumcount-name",
223     proc_macro_derive(StrumEnumCount, attributes(strum))
224 )]
225 #[cfg_attr(
226     not(feature = "verbose-enumcount-name"),
227     proc_macro_derive(EnumCount, attributes(strum))
228 )]
enum_count(input: proc_macro::TokenStream) -> proc_macro::TokenStream229 pub fn enum_count(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
230     let ast = syn::parse(input).unwrap();
231     let toks = macros::enum_count::enum_count_inner(&ast);
232     debug_print_generated(&ast, &toks);
233     toks.into()
234 }
235