use quote::quote;
use syn::{Expr, Path, Type};
pub(crate) fn get_output_file_name_code(attrs: &[(String, String)]) -> proc_macro2::TokenStream {
let output_file_name_simple = get_attr_value(&attrs, "output_file_name_simple");
if let Some(output_file_name_simple) = output_file_name_simple {
#[cfg(feature = "date")]
{
let is_add_date = get_attr_value(&attrs, "output_file_name_add_date")
.map(|value| value == "true")
.unwrap_or(false);
quote! {
const OUTPUT_FILE_NAME_GETTER_SIMPLE: Option<OutputFileNameSimpleGetter> =
Some(OutputFileNameSimpleGetter::new(
#output_file_name_simple,
#is_add_date,
));
}
}
#[cfg(not(feature = "date"))]
quote! {
const OUTPUT_FILE_NAME_GETTER_SIMPLE: Option<OutputFileNameSimpleGetter> =
Some(OutputFileNameSimpleGetter::new(
#output_file_name_simple
));
}
} else if let Some(output_file_name_advance) =
get_attr_value(&attrs, "output_file_name_advance")
{
let output_file_name_advance =
syn::parse_str::<Path>(&output_file_name_advance).expect("个性化文件名称获取器非函数");
let extra_arg_type = get_attr_value(&attrs, "extra_arg_type");
if extra_arg_type.is_some() {
quote! {
#[allow(unused_variables)]
fn get_output_file_name_advance_with_extra_arg(group_id: &str,extra_arg:Option<&Self::ExtraArgType>) -> String {
#output_file_name_advance(group_id,extra_arg)
}
}
} else {
quote! {
#[allow(unused_variables)]
fn get_output_file_name_advance(group_id: &str) -> String {
#output_file_name_advance(group_id)
}
}
}
} else {
quote! {}
}
}
pub(crate) fn get_custom_info_adder_code(attrs: &[(String, String)]) -> proc_macro2::TokenStream {
if let Some(custom_info_adder) = get_attr_value(&attrs, "custom_info_adder") {
let custom_info_adder =
syn::parse_str::<Path>(&custom_info_adder).expect("个性化信息添加器非函数");
let extra_arg_type = get_attr_value(&attrs, "extra_arg_type");
if extra_arg_type.is_some() {
quote! {
fn add_custom_info_to_sheet_with_extra_arg(sheet: &mut Worksheet, group_id: &str,extra_arg:Option<&Self::ExtraArgType>) {
#custom_info_adder(sheet,group_id,extra_arg)
}
}
} else {
quote! {
fn add_custom_info_to_sheet(sheet: &mut Worksheet, group_id: &str) {
#custom_info_adder(sheet,group_id)
}
}
}
} else {
quote! {}
}
}
pub(crate) fn get_template_code(attrs: &[(String, String)]) -> proc_macro2::TokenStream {
let template_simple = get_attr_value(&attrs, "template_simple");
if let Some(template_simple) = template_simple {
quote! {
fn get_template() -> XlsxInitTemplet {
XlsxInitTemplet::new_header(#template_simple)
}
}
} else if let Some(template_advance) = get_attr_value(&attrs, "template_advance") {
if template_advance.contains(',') {
let config: Vec<_> = template_advance.split(',').collect();
let temp_path = config[0];
let start_line: u32 = config[1].parse().expect("解析高级模板起始数据行错误");
quote! {
fn get_template() -> XlsxInitTemplet {
XlsxInitTemplet::new_advance(#temp_path, #start_line)
}
}
} else {
quote! {}
}
} else if let Some(template_getter) = get_attr_value(&attrs, "template_getter") {
let template_getter =
syn::parse_str::<Path>(&template_getter).expect("个性化模板获取器非函数");
quote! {
fn get_template() -> XlsxInitTemplet{
#template_getter()
}
}
} else {
quote! {}
}
}
pub(crate) fn get_group_make_code(attrs: &[(String, String)]) -> proc_macro2::TokenStream {
let group_maker = get_attr_value(&attrs, "group_maker");
if let Some(group_maker) = group_maker {
let group_id_expr: Expr =
syn::parse_str(&group_maker).expect(&format!("{group_maker} 不是合法表达式"));
quote! {
fn group_make(&self) -> &str {
#group_id_expr
}
}
} else {
quote! {}
}
}
pub(crate) fn get_line_writer_code(attrs: &[(String, String)]) -> proc_macro2::TokenStream {
let line_writer_simple = get_attr_value(&attrs, "line_writer_simple");
if let Some(line_writer_simple) = line_writer_simple {
let items: Vec<_> = line_writer_simple
.split(',')
.map(|item| {
if item.contains(':') {
let value_type: Vec<&str> = item.split(':').map(|inner| inner.trim()).collect();
let value: syn::Expr = syn::parse_str(value_type[0])
.expect(&format!("{} 不是合法表达式", value_type[0]));
let cell_type = if value_type[1] == "number" {
quote!(XlsxColValueType::NumberValue)
} else {
quote!(XlsxColValueType::StringValue)
};
(value, cell_type)
} else {
let value: syn::Expr =
syn::parse_str(item.trim()).expect(&format!("{item} 不是合法表达式"));
let cell_type = quote!(XlsxColValueType::StringValue);
(value, cell_type)
}
})
.collect();
let values: Vec<_> = items.iter().map(|(value, _)| value).collect();
let types: Vec<_> = items.iter().map(|(_, cell_type)| cell_type).collect();
quote! {
const LINE_WRITER_MODEL: XlsxLineWriterModel = XlsxLineWriterModel::Simple;
fn line_writer_simple(&self, line_index: u32) -> Vec<XlsxColValue> {
vec![
#(XlsxColValue::new(#values,#types)),*
]
}
}
} else if let Some(line_writer_advance) = get_attr_value(&attrs, "line_writer_advance") {
let line_writer_advance =
syn::parse_str::<Path>(&line_writer_advance).expect("行高级写入器非函数");
quote! {
const LINE_WRITER_MODEL: XlsxLineWriterModel = XlsxLineWriterModel::Advance;
#[allow(unused_variables)]
fn line_writer_advance(
&self,
sheet: &mut Worksheet,
line_index: u32,
) -> Option<XlsxLineAdvanceWriterResult> {
#line_writer_advance(self,sheet,line_index)
}
}
} else if let Some(line_writer_advance_with_extra_arg) = get_attr_value(&attrs, "line_writer_advance_with_extra_arg") {
let line_writer_advance_with_extra_arg =
syn::parse_str::<Path>(&line_writer_advance_with_extra_arg).expect("行高级写入器非函数");
quote! {
const LINE_WRITER_MODEL: XlsxLineWriterModel = XlsxLineWriterModel::Advance;
#[allow(unused_variables)]
fn line_writer_advance_with_extra_arg(
&self,
sheet: &mut Worksheet,
line_index: u32,
extra_arg: Option<&Self::ExtraArgType>,
) -> Option<XlsxLineAdvanceWriterResult> {
#line_writer_advance_with_extra_arg(self,sheet,line_index,extra_arg)
}
}
}else {
quote! {}
}
}
pub(crate) fn get_extra_arg_type_code(attrs: &[(String, String)]) -> proc_macro2::TokenStream {
let extra_arg_type = get_attr_value(&attrs, "extra_arg_type");
if let Some(extra_arg_type) = extra_arg_type {
let extra_arg_type: Type =
syn::parse_str(&extra_arg_type).expect(&format!("{extra_arg_type} 不是合法类型"));
quote! {
type ExtraArgType = #extra_arg_type ;
}
} else {
quote! {
type ExtraArgType = () ;
}
}
}
fn get_attr_value(attrs: &[(String, String)], name: &str) -> Option<String> {
attrs
.iter()
.find_map(|attr| (attr.0 == name).then(|| attr.1.clone()))
}