xlsx_group_write_macro_derive/
lib.rs#![doc = include_str!("../README.md")]
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput, Lit, Meta, MetaList, MetaNameValue, NestedMeta};
#[proc_macro_derive(XlsxGroupWriteQuicker, attributes(xlsx_group_write))]
pub fn derive_main(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
impl_trait(&ast)
}
fn parse_attrs(ast: &syn::DeriveInput) -> Vec<(String, String)> {
ast.attrs.iter().find_map(|attr| {
if attr.path.is_ident("xlsx_group_write") {
attr.parse_meta().ok().map(|meta| {
if let Meta::List(MetaList { nested, .. }) = meta {
let args: Vec<_> = nested
.iter()
.filter_map(|nested_meta| {
if let NestedMeta::Meta(Meta::NameValue(MetaNameValue {
path,
lit,
..
})) = nested_meta
{
let name = path.get_ident().unwrap().to_string();
if path.is_ident("line_writer_simple") ||
path.is_ident("group_maker") ||
path.is_ident("template_simple") ||
path.is_ident("output_file_name_simple") ||
path.is_ident("output_file_name_add_date") ||
path.is_ident("template_advance") ||
path.is_ident("custom_info_adder") ||
path.is_ident("line_writer_advance") ||
path.is_ident("line_writer_advance_with_extra_arg") ||
path.is_ident("output_file_name_advance") ||
path.is_ident("extra_arg_type") ||
path.is_ident("template_getter"){
match lit {
Lit::Str(lit_str) => Some((name, lit_str.value())),
_ => panic!(
"xlsx_group_write attribute err,must be:line_writer_simple \
group_maker template_simple output_file_name_simple \
output_file_name_add_date template_advance custom_info_adder \
line_writer_advance output_file_name_advance template_getter \
extra_arg_type line_writer_advance_with_extra_arg"
),
}
} else {
None
}
} else {
None
}
})
.collect();
args
} else {
panic!("xlsx_group_write attribute err")
}
})
} else {
None
}
}).unwrap_or_default()
}
fn impl_trait(ast: &syn::DeriveInput) -> TokenStream {
let struct_name = &ast.ident;
let (impl_generics, ty_generics, where_clause) = &ast.generics.split_for_impl();
let attrs = parse_attrs(ast);
let line_writer_code = code::get_line_writer_code(&attrs);
let group_maker_code = code::get_group_make_code(&attrs);
let template_code = code::get_template_code(&attrs);
let custom_info_adder_code = code::get_custom_info_adder_code(&attrs);
let output_file_name_code = code::get_output_file_name_code(&attrs);
let extra_arg_type_code = code::get_extra_arg_type_code(&attrs);
quote! {
impl #impl_generics XlsxGroupWrite for #struct_name #ty_generics #where_clause {
#extra_arg_type_code
#line_writer_code
#group_maker_code
#template_code
#output_file_name_code
#custom_info_adder_code
}
}
.into()
}
mod code;