enum_to_string_macros/
lib.rs

1#![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}