aboutsummaryrefslogtreecommitdiff
path: root/mingling_macros/src/suggest.rs
diff options
context:
space:
mode:
Diffstat (limited to 'mingling_macros/src/suggest.rs')
-rw-r--r--mingling_macros/src/suggest.rs72
1 files changed, 72 insertions, 0 deletions
diff --git a/mingling_macros/src/suggest.rs b/mingling_macros/src/suggest.rs
new file mode 100644
index 0000000..886eee0
--- /dev/null
+++ b/mingling_macros/src/suggest.rs
@@ -0,0 +1,72 @@
+use proc_macro::TokenStream;
+use quote::quote;
+use syn::parse::{Parse, ParseStream};
+use syn::punctuated::Punctuated;
+use syn::{Expr, LitStr, Token, parse_macro_input};
+
+struct SuggestInput {
+ items: Punctuated<SuggestItem, Token![,]>,
+}
+
+enum SuggestItem {
+ WithDesc(Box<(LitStr, Expr)>), // "-i" = "Insert something"
+ Simple(LitStr), // "-I"
+}
+
+impl Parse for SuggestInput {
+ fn parse(input: ParseStream) -> syn::Result<Self> {
+ let items = Punctuated::parse_terminated(input)?;
+ Ok(SuggestInput { items })
+ }
+}
+
+impl Parse for SuggestItem {
+ fn parse(input: ParseStream) -> syn::Result<Self> {
+ let key: LitStr = input.parse()?;
+
+ if input.peek(Token![:]) {
+ let _colon: Token![:] = input.parse()?;
+ let value: Expr = input.parse()?;
+ Ok(SuggestItem::WithDesc(Box::new((key, value))))
+ } else {
+ Ok(SuggestItem::Simple(key))
+ }
+ }
+}
+
+#[cfg(feature = "comp")]
+pub fn suggest(input: TokenStream) -> TokenStream {
+ let input = parse_macro_input!(input as SuggestInput);
+
+ let mut 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())
+ });
+ }
+ SuggestItem::Simple(key) => {
+ items.push(quote! {
+ ::mingling::SuggestItem::new(#key.to_string())
+ });
+ }
+ }
+ }
+
+ let expanded = if items.is_empty() {
+ quote! {
+ ::mingling::Suggest::default()
+ }
+ } else {
+ quote! {{
+ let mut suggest = ::mingling::Suggest::default();
+ #(suggest.insert(#items);)*
+ suggest
+ }}
+ };
+
+ expanded.into()
+}