diff options
Diffstat (limited to 'mingling_macros/src/func/suggest.rs')
| -rw-r--r-- | mingling_macros/src/func/suggest.rs | 64 |
1 files changed, 31 insertions, 33 deletions
diff --git a/mingling_macros/src/func/suggest.rs b/mingling_macros/src/func/suggest.rs index 0f2026f..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,60 +34,58 @@ 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 }} }; expanded.into() } - -pub(crate) fn suggest_enum(input: TokenStream) -> TokenStream { - let enum_type = parse_macro_input!(input as syn::Type); - - let expanded = quote! {{ - let mut enum_suggest = ::mingling::Suggest::new(); - for (name, desc) in <#enum_type>::enums() { - if desc.is_empty() { - enum_suggest.insert(::mingling::SuggestItem::new(name.to_string())); - } else { - enum_suggest.insert(::mingling::SuggestItem::new_with_desc( - name.to_string(), - desc.to_string(), - )); - } - } - enum_suggest - }}; - - expanded.into() -} |
