xlsx_group_write_macro_derive 0.4.3

excel-group-write 辅助派生宏
Documentation
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! {
                /// 输出xlsx文件名设置
                const OUTPUT_FILE_NAME_GETTER_SIMPLE: Option<OutputFileNameSimpleGetter> =
                Some(OutputFileNameSimpleGetter::new(
                    #output_file_name_simple,
                    #is_add_date,
                ));
            }
        }
        #[cfg(not(feature = "date"))]
        quote! {
            /// 输出xlsx文件名设置
            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 {
        // @todo 高级设置
        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 {
        // @todo 高级设置
        quote! {}
    }
}

/// 获取xlsx模板相关代码实现
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! {
                /// 从模板创建导出xlsx文件
                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! {
            /// 从外部函数获取输出xlsx文件模板
            ///
            /// 用于初始化表标题、表头等
            fn get_template() -> XlsxInitTemplet{
                #template_getter()
            }
        }
    } else {
        // @todo 高级设置
        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! {
            /// 设置分组id
            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! {
            /// 每行数据写入方式为简便模式
            /// 即直接根据line_writer_simple返回的对照表自动写入数据
            /// 无需了解xlsx写入api
            const LINE_WRITER_MODEL: XlsxLineWriterModel = XlsxLineWriterModel::Simple;

            /// 每一行数据写入方法
            /// # 参数说明
            ///
            /// * line_index 为正在写入行的行号,行号从1开始计数。
            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! {
            /// 每行数据写入方式为高级模式
            /// 自行通过xlsx写入api自由写入
            const LINE_WRITER_MODEL: XlsxLineWriterModel = XlsxLineWriterModel::Advance;
            /// 每一行数据的xlsx对应行的各列数据的方法
            ///
            /// 自动遍历数据,并调用该方法写入xlsx数据
            ///
            /// 高级模式
            ///
            /// 可完整自行控制如何写入xlsx数据,比如合并写入、自定义写入格式等
            ///
            /// # 参数说明
            ///
            /// * sheet 正在写入的xlsx工作表
            /// * line_index 正在写入行的行号,行号从1开始计数。
            #[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! {
            /// 每行数据写入方式为高级模式
            /// 自行通过xlsx写入api自由写入
            const LINE_WRITER_MODEL: XlsxLineWriterModel = XlsxLineWriterModel::Advance;
            /// 每一行数据的xlsx对应行的各列数据的方法
            ///
            /// 自动遍历数据,并调用该方法写入xlsx数据
            ///
            /// 高级模式
            ///
            /// 可完整自行控制如何写入xlsx数据,比如合并写入、自定义写入格式等
            ///
            /// # 参数说明
            ///
            /// * sheet 正在写入的xlsx工作表
            /// * line_index 正在写入行的行号,行号从1开始计数。
            /// * extra_arg 额外通过wirte传入的参数
            #[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()))
}