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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
extern crate proc_macro; mod gen; use proc_macro::TokenStream; use quote::format_ident; use quote::quote; use syn::{parse_macro_input, Data, DeriveInput, Field, Fields, Ident}; #[proc_macro_derive(QueryBuilder, attributes(query_builder_ignore, query_builder_rename))] pub fn derive(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); let ident = &input.ident; let builder_ident = format_ident!("{}{}", ident, "LuceneQueryBuilder"); let fields: Vec<Field> = match input.data { Data::Struct(struct_) => match struct_.fields { Fields::Named(n) => n.named.iter().cloned().collect(), Fields::Unnamed(_) => panic!("Unexpected unnamed field"), Fields::Unit => panic!("Unexpected unit"), }, Data::Enum(_) => panic!("The Builder macro is not to be used on enum"), Data::Union(_) => panic!("The Builder macro is not to be used on union"), }; let field_idents: Vec<Ident> = gen::get_field_idents(fields); let common_functions = gen::common_functions(); let query_builder_fn = gen::query_builder_fn(ident, &builder_ident); let query_builder = gen::query_builder(&builder_ident); let query_field_fn = gen::query_field_fn(&field_idents); let range_query_field_fn = gen::range_query_field_fn(&field_idents); let output = quote! { use lucene_query_builder::*; #query_builder_fn #query_builder impl #builder_ident { #query_field_fn #range_query_field_fn #common_functions } }; TokenStream::from(output) }