enum_to_string_macros/
lib.rs1#![feature(proc_macro_hygiene)]
2#![feature(proc_macro_span)]
3
4extern crate proc_macro;
5mod attrs;
6mod ast;
7mod dgen;
8mod error;
9
10use attrs::*;
11use ast::*;
12use dgen::*;
13use error::*;
14use quote::quote;
15use proc_macro2::TokenStream;
16
17
18#[proc_macro_derive(EnumToString)]
19pub fn enum_to_string_macro_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
20 let (mut dgen, basic) = match impl_enum_to_string_macro_methods(input) {
21 Ok(t) => t,
22 Err(e) => return e.into()
23 };
24
25 let debug_impl = if dgen.can_impl_debug_enum() {
26 dgen.impl_debug_enum()
27 } else {
28 TokenStream::new()
29 };
30 let display_impl = if dgen.can_impl_display_enum() {
31 dgen.impl_display_enum()
32 } else {
33 TokenStream::new()
34 };
35
36
37 quote! {
38 #basic
39 #display_impl
40 #debug_impl
41 }.into()
42}
43
44#[proc_macro_attribute]
45pub fn enum_to_string(
46 attrs: proc_macro::TokenStream,
47 item: proc_macro::TokenStream,
48) -> proc_macro::TokenStream {
49 if let Err(e) = EnumToStringAttrs::flags_from_tokenstream(attrs.into()) {
50 return e.into()
51 }
52 item
53}
54
55
56fn impl_enum_to_string_macro_methods(input: proc_macro::TokenStream) -> Result<(DeriveGen, TokenStream), TokenStream> {
57 let mut dgen = match DeriveGen::parse_input(input) {
58 Ok(dgen) => dgen,
59 Err(e) => return Err(e.into()),
60 };
61
62 let name = dgen.enum_ident();
63 let (impl_variants, str_variant_matches, dbg_variant_matches) = dgen.impl_enum_to_string_variants();
64
65 Ok((dgen, quote! {
66 #impl_variants
67 impl EnumToString for #name {
68 fn as_str(&self) -> &'static str {
69 match self {
70 #str_variant_matches
71 }
72 }
73 fn as_dbg(&self) -> &'static str {
74 match self {
75 #dbg_variant_matches
76 }
77 }
78 }
79 }))
80}