aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/crates/macros/src
diff options
context:
space:
mode:
author苏向夜 <fu050409@163.com>2026-02-15 15:29:49 +0800
committer苏向夜 <fu050409@163.com>2026-02-15 15:33:04 +0800
commite0dd58c443ed4d13e69b511bb01e17922926076f (patch)
treee0a7b3ea8921c469f179c8f3980b2ef34d4a71cf /crates/macros/src
parenta83363bccada6013d3f03efedeff22b45a578da7 (diff)
downloadDropOut-e0dd58c443ed4d13e69b511bb01e17922926076f.tar.gz
DropOut-e0dd58c443ed4d13e69b511bb01e17922926076f.zip
refactor(macros): use darling to parse macro metas
Diffstat (limited to 'crates/macros/src')
-rw-r--r--crates/macros/src/attr.rs10
-rw-r--r--crates/macros/src/lib.rs41
2 files changed, 25 insertions, 26 deletions
diff --git a/crates/macros/src/attr.rs b/crates/macros/src/attr.rs
new file mode 100644
index 0000000..ef1df86
--- /dev/null
+++ b/crates/macros/src/attr.rs
@@ -0,0 +1,10 @@
+use darling::FromMeta;
+
+#[derive(Default, FromMeta)]
+#[darling(default)]
+#[darling(derive_syn_parse)]
+pub struct MacroArgs {
+ pub export_to: Option<String>,
+ pub export_to_path: Option<String>,
+ pub import_from: Option<String>,
+}
diff --git a/crates/macros/src/lib.rs b/crates/macros/src/lib.rs
index 1b26bf2..9e310ca 100644
--- a/crates/macros/src/lib.rs
+++ b/crates/macros/src/lib.rs
@@ -6,6 +6,10 @@ use syn::{
Expr, FnArg, Ident, ItemFn, Lit, MetaNameValue, Pat, PathArguments, ReturnType, Type,
};
+use crate::attr::MacroArgs;
+
+mod attr;
+
fn get_lit_str_value(nv: &MetaNameValue) -> Option<String> {
// In syn v2 MetaNameValue.value is an Expr (usually Expr::Lit). Extract string literal if present.
match &nv.value {
@@ -180,35 +184,20 @@ fn snake_to_camel(s: &str) -> String {
#[proc_macro_attribute]
pub fn api(attr: TokenStream, item: TokenStream) -> TokenStream {
- // Parse inputs as a punctuated list of MetaNameValue (e.g. export_to = "...", import_from = "...")
- // `MetaList` implements `Parse` so we can parse the raw attribute token stream reliably
- struct MetaList(Punctuated<MetaNameValue, Comma>);
- impl Parse for MetaList {
- fn parse(input: ParseStream) -> syn::Result<Self> {
- Ok(MetaList(Punctuated::parse_terminated(input)?))
- }
- }
- let metas = parse_macro_input!(attr as MetaList).0;
+ // Parse attribute args via `darling` crate
+ let meta: MacroArgs = match syn::parse(attr) {
+ Ok(meta) => meta,
+ Err(err) => return err.into_compile_error().into(),
+ };
let input_fn = parse_macro_input!(item as ItemFn);
// Extract attribute args: export_to, import_from
- let mut export_to: Option<String> = None;
- let mut import_from: Option<String> = None;
-
- for nv in metas.iter() {
- if let Some(ident) = nv.path.get_ident() {
- let name = ident.to_string();
- if name == "export_to" {
- if let Some(v) = get_lit_str_value(nv) {
- export_to = Some(v);
- }
- } else if name == "import_from" {
- if let Some(v) = get_lit_str_value(nv) {
- import_from = Some(v);
- }
- }
- }
- }
+ let export_to = match (meta.export_to, meta.export_to_path) {
+ (Some(to), None) => Some(to),
+ (_, Some(path)) => Some(path),
+ (None, None) => None,
+ };
+ let import_from = meta.import_from;
// Analyze function
let fn_name_ident: Ident = input_fn.sig.ident.clone();