From 0a2ef958c0dca21d19e4ffc38ba5a7c4078e182a Mon Sep 17 00:00:00 2001 From: Weicao-CatilGrass <1992414357@qq.com> Date: Sat, 23 May 2026 23:41:04 +0800 Subject: Rework examples and add entry macro for testing --- mingling_macros/src/entry.rs | 75 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 mingling_macros/src/entry.rs (limited to 'mingling_macros/src/entry.rs') diff --git a/mingling_macros/src/entry.rs b/mingling_macros/src/entry.rs new file mode 100644 index 0000000..6237e41 --- /dev/null +++ b/mingling_macros/src/entry.rs @@ -0,0 +1,75 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::{Ident, LitStr, parse_macro_input}; + +enum EntryInput { + Typed { ident: Ident, strings: Vec }, + Untyped { strings: Vec }, +} + +impl syn::parse::Parse for EntryInput { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + // entry!(EntryType, ["a", "b", "c"]) + // entry!["a", "b", "c"] — comes in as just ["a", "b", "c"] + if input.peek(Ident) && input.peek2(syn::Token![,]) { + // entry!(EntryType, ["a", "b", "c"]) + let ident: Ident = input.parse()?; + let _comma: syn::Token![,] = input.parse()?; + let content; + syn::bracketed!(content in input); + let strings = parse_strings(&content)?; + Ok(EntryInput::Typed { ident, strings }) + } else { + // entry!["a", "b", "c"] — bare bracket content + let strings = parse_strings(input)?; + Ok(EntryInput::Untyped { strings }) + } + } +} + +fn parse_strings(input: &syn::parse::ParseBuffer) -> syn::Result> { + let mut strings = Vec::new(); + while !input.is_empty() { + let s: LitStr = input.parse()?; + strings.push(s.value()); + if input.peek(syn::Token![,]) { + let _comma: syn::Token![,] = input.parse()?; + } + } + Ok(strings) +} + +pub fn entry(input: TokenStream) -> TokenStream { + let parsed = parse_macro_input!(input as EntryInput); + + let string_exprs = match &parsed { + EntryInput::Typed { .. } | EntryInput::Untyped { .. } => { + let strings = match &parsed { + EntryInput::Typed { strings, .. } => strings, + EntryInput::Untyped { strings } => strings, + }; + strings + .iter() + .map(|s| { + let lit = syn::LitStr::new(s, proc_macro2::Span::call_site()); + quote! { #lit.to_string() } + }) + .collect::>() + } + }; + + let expanded = match parsed { + EntryInput::Typed { ident, .. } => { + quote! { + #ident::new(vec![#(#string_exprs),*]) + } + } + EntryInput::Untyped { .. } => { + quote! { + vec![#(#string_exprs),*].into() + } + } + }; + + expanded.into() +} -- cgit