summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2025-09-20 16:25:15 +0800
committer魏曹先生 <1992414357@qq.com>2025-09-20 16:25:15 +0800
commit1fbdf2882be1b2b84cb9246866dabc0d40cad099 (patch)
tree116826d23199d46a73b8d88b35ec23dc2dc39856
parentdd679c9f0cd0b936a9e3e480400097cd5115f499 (diff)
Update cfg_file_derive
-rw-r--r--crates/utils/cfg_file/cfg_file_derive/src/lib.rs44
1 files changed, 31 insertions, 13 deletions
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<String> {
+enum PathExpr {
+ StringLiteral(String),
+ PathExpression(syn::Expr),
+}
+
+fn find_cfg_file_path(attrs: &[Attribute]) -> Option<PathExpr> {
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);
}
}
}