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
extern crate proc_macro;
extern crate syn;
#[macro_use]
extern crate quote;

use proc_macro::TokenStream;
use syn::*;
mod enum_data;
mod variant_data;
mod generics;

/// Generates the `PrefixOpt` impl.
#[proc_macro_derive(PrefixOpt, attributes(prefixopt))]
pub fn prefixopt(input: TokenStream) -> TokenStream {
    let s = input.to_string();
    let ast = syn::parse_derive_input(&s).unwrap();
    let gen = impl_prefixopt(ast);
    gen.parse().unwrap()
}

fn impl_prefixopt(ast: DeriveInput) -> quote::Tokens {
    let ref ident = ast.ident;
    let generics = generics::with_prefixopt_constraints(ast.generics);
    let tokens = match ast.body {
        syn::Body::Struct(_struct) => variant_data::derive(&generics, ident, &_struct),
        syn::Body::Enum(_enum) => {
            let generics = generics::with_default_constraints(generics);
            enum_data::derive(&generics, ident, &_enum)
        },
    };
    tokens
}