diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-08-02 12:11:47 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-08-02 12:11:47 +0800 |
| commit | 43fadfa22b1f28382338c892d91a6c388b5e540c (patch) | |
| tree | fb986e1d4fa65801a8ced895e43c135921328cad /mingling_macros | |
| parent | 0f9ca0745e3e80c751404f45cb2b97d4d14c97d3 (diff) | |
feat(core): add batch methods to Suggest and update macro
Add `add_suggest()` and `add_suggest_with_description()` methods to
`Suggest` for ergonomic batch population of suggestion sets from
collections of strings.
Update the `suggest!` macro to use these new methods and accept
expressions beyond string literals for suggestion items.
Diffstat (limited to 'mingling_macros')
| -rw-r--r-- | mingling_macros/src/func/suggest.rs | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/mingling_macros/src/func/suggest.rs b/mingling_macros/src/func/suggest.rs index 85f1afe..6613a98 100644 --- a/mingling_macros/src/func/suggest.rs +++ b/mingling_macros/src/func/suggest.rs @@ -2,15 +2,15 @@ use proc_macro::TokenStream; use quote::quote; use syn::parse::{Parse, ParseStream}; use syn::punctuated::Punctuated; -use syn::{Expr, LitStr, Token, parse_macro_input}; +use syn::{Expr, Token, parse_macro_input}; struct SuggestInput { items: Punctuated<SuggestItem, Token![,]>, } enum SuggestItem { - WithDesc(Box<(LitStr, Expr)>), // "-i" = "Insert something" - Simple(LitStr), // "-I" + WithDesc(Box<(Expr, Expr)>), // "-i" = "Insert something" + Simple(Expr), // "-I" } impl Parse for SuggestInput { @@ -22,7 +22,7 @@ impl Parse for SuggestInput { impl Parse for SuggestItem { fn parse(input: ParseStream) -> syn::Result<Self> { - let key: LitStr = input.parse()?; + let key: Expr = input.parse()?; if input.peek(Token![:]) { let _colon: Token![:] = input.parse()?; @@ -34,36 +34,55 @@ impl Parse for SuggestItem { } } +/// 判断表达式是否是一个纯字符串字面量(仅由一对引号包裹) +fn is_pure_lit_str(expr: &Expr) -> bool { + matches!(expr, Expr::Lit(lit) if matches!(lit.lit, syn::Lit::Str(_))) +} + #[cfg(feature = "comp")] pub(crate) fn suggest(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as SuggestInput); let mut items = Vec::new(); + let mut simple_items = Vec::new(); for item in input.items { match item { SuggestItem::WithDesc(boxed) => { let (key, value) = *boxed; - items.push(quote! { - ::mingling::SuggestItem::new_with_desc(#key.to_string(), #value.to_string()) - }); + if is_pure_lit_str(&key) { + items.push(quote! { + vec![#key .to_string()], #value + }); + } else { + items.push(quote! { + #key, #value + }); + } } SuggestItem::Simple(key) => { - items.push(quote! { - ::mingling::SuggestItem::new(#key.to_string()) - }); + if is_pure_lit_str(&key) { + simple_items.push(quote! { + vec![#key .to_string()] + }); + } else { + simple_items.push(quote! { + #key + }); + } } } } - let expanded = if items.is_empty() { + let expanded = if items.is_empty() && simple_items.is_empty() { quote! { ::mingling::Suggest::new() } } else { quote! {{ let mut suggest = ::mingling::Suggest::new(); - #(suggest.insert(#items);)* + #(suggest.add_suggest_with_description(#items);)* + #(suggest.add_suggest(#simple_items);)* suggest }} }; |
