aboutsummaryrefslogtreecommitdiff
path: root/mingling_macros
diff options
context:
space:
mode:
Diffstat (limited to 'mingling_macros')
-rw-r--r--mingling_macros/src/func/suggest.rs43
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
}}
};