From 1fbdf2882be1b2b84cb9246866dabc0d40cad099 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Sat, 20 Sep 2025 16:25:15 +0800 Subject: Update cfg_file_derive --- crates/utils/cfg_file/cfg_file_derive/src/lib.rs | 44 +++++++++++++++++------- 1 file changed, 31 insertions(+), 13 deletions(-) (limited to 'crates/utils/cfg_file/cfg_file_derive/src/lib.rs') diff --git a/crates/utils/cfg_file/cfg_file_derive/src/lib.rs b/crates/utils/cfg_file/cfg_file_derive/src/lib.rs index 66a6d6f..e50a929 100644 --- a/crates/utils/cfg_file/cfg_file_derive/src/lib.rs +++ b/crates/utils/cfg_file/cfg_file_derive/src/lib.rs @@ -3,7 +3,7 @@ extern crate proc_macro; use proc_macro::TokenStream; use quote::quote; use syn::parse::ParseStream; -use syn::{Attribute, DeriveInput, parse_macro_input}; +use syn::{Attribute, DeriveInput, Expr, parse_macro_input}; #[proc_macro_derive(ConfigFile, attributes(cfg_file))] pub fn derive_config_file(input: TokenStream) -> TokenStream { @@ -12,7 +12,7 @@ pub fn derive_config_file(input: TokenStream) -> TokenStream { // Process 'cfg_file' let path_expr = match find_cfg_file_path(&input.attrs) { - Some(path) => { + Some(PathExpr::StringLiteral(path)) => { if let Some(path_str) = path.strip_prefix("./") { quote! { std::env::current_dir()?.join(#path_str) @@ -24,6 +24,12 @@ pub fn derive_config_file(input: TokenStream) -> TokenStream { } } } + Some(PathExpr::PathExpression(path_expr)) => { + // For path expressions (constants), generate code that references the constant + quote! { + std::path::PathBuf::from(#path_expr) + } + } None => { let default_file = to_snake_case(&name.to_string()) + ".json"; quote! { @@ -45,24 +51,36 @@ pub fn derive_config_file(input: TokenStream) -> TokenStream { TokenStream::from(expanded) } -fn find_cfg_file_path(attrs: &[Attribute]) -> Option { +enum PathExpr { + StringLiteral(String), + PathExpression(syn::Expr), +} + +fn find_cfg_file_path(attrs: &[Attribute]) -> Option { for attr in attrs { if attr.path().is_ident("cfg_file") { let parser = |meta: ParseStream| { let path_meta: syn::MetaNameValue = meta.parse()?; - if path_meta.path.is_ident("path") - && let syn::Expr::Lit(syn::ExprLit { - lit: syn::Lit::Str(lit), - .. - }) = path_meta.value - { - return Ok(lit.value()); + if path_meta.path.is_ident("path") { + match &path_meta.value { + // String literal case: path = "./vault.toml" + Expr::Lit(expr_lit) if matches!(expr_lit.lit, syn::Lit::Str(_)) => { + if let syn::Lit::Str(lit_str) = &expr_lit.lit { + return Ok(PathExpr::StringLiteral(lit_str.value())); + } + } + // Path expression case: path = SERVER_FILE_VAULT or crate::constants::SERVER_FILE_VAULT + expr @ (Expr::Path(_) | Expr::Macro(_)) => { + return Ok(PathExpr::PathExpression(expr.clone())); + } + _ => {} + } } - Err(meta.error("expected `path = \"...\"`")) + Err(meta.error("expected `path = \"...\"` or `path = CONSTANT`")) }; - if let Ok(path) = attr.parse_args_with(parser) { - return Some(path); + if let Ok(path_expr) = attr.parse_args_with(parser) { + return Some(path_expr); } } } -- cgit