50 lines
1.2 KiB
Rust
50 lines
1.2 KiB
Rust
extern crate proc_macro;
|
|
|
|
mod attr;
|
|
mod gen_struct;
|
|
mod gen_enum;
|
|
|
|
use gen_struct::gen_parse_struct;
|
|
use gen_enum::gen_parse_enum;
|
|
|
|
use proc_macro::TokenStream;
|
|
use quote::quote;
|
|
use syn;
|
|
|
|
#[proc_macro_derive(Parse, attributes(parse))]
|
|
pub fn parse_derive_macro(input: TokenStream) -> TokenStream {
|
|
let input = syn::parse_macro_input!(input as syn::DeriveInput);
|
|
|
|
impl_parse_derive_macro(&input)
|
|
}
|
|
|
|
fn impl_parse_derive_macro(ast: &syn::DeriveInput) -> TokenStream {
|
|
|
|
//println!("{:#?}", ast);
|
|
|
|
let gattr = attr::Global::from_ast(&ast);
|
|
let name = gattr.name();
|
|
|
|
let use_bind_conf = gattr.gen_use_bind_conf();
|
|
|
|
let content = match &ast.data {
|
|
syn::Data::Enum(ref data) => gen_parse_enum(&data, &gattr),
|
|
syn::Data::Struct(ref data) => gen_parse_struct(&data, &gattr),
|
|
_ => panic!("Parse derive macro can only be applied on Enum and Struct")
|
|
};
|
|
|
|
let expanded = quote! {
|
|
const _:() = {
|
|
#use_bind_conf
|
|
|
|
impl<'a> Parse<'a> for #name {
|
|
fn parse(pa: &mut Parser) -> Result<Self> {
|
|
#content
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
TokenStream::from(expanded)
|
|
}
|