From 820f1d7e0c19a57c8e6d2d9b66d250f630c2ffc0 Mon Sep 17 00:00:00 2001 From: FroVolod Date: Tue, 6 Sep 2022 11:46:45 +0300 Subject: [PATCH] added "disable_back" to enums --- .../methods/choose_variant.rs | 198 +++++++++--------- 1 file changed, 104 insertions(+), 94 deletions(-) diff --git a/interactive_clap_derive/src/derives/interactive_clap/methods/choose_variant.rs b/interactive_clap_derive/src/derives/interactive_clap/methods/choose_variant.rs index b507c31..13cfa4e 100644 --- a/interactive_clap_derive/src/derives/interactive_clap/methods/choose_variant.rs +++ b/interactive_clap_derive/src/derives/interactive_clap/methods/choose_variant.rs @@ -18,6 +18,8 @@ pub fn fn_choose_variant( let variant_ident = &variants[0].ident; let mut cli_variant = quote!(); + let mut actions_push_back = quote! {actions.push("back".to_string())}; + let mut ast_attrs: Vec<&str> = std::vec::Vec::new(); if !ast.attrs.is_empty() { for attr in ast.attrs.clone() { @@ -31,21 +33,9 @@ pub fn fn_choose_variant( .contains("disable_strum_discriminants") .clone() { - match &variants[0].fields { - syn::Fields::Unnamed(_) => { - cli_variant = quote! { - let cli_variant = #cli_command::#variant_ident(Default::default()); - }; - } - syn::Fields::Unit => { - cli_variant = quote! { - let cli_variant = #cli_command::#variant_ident; - }; - } - _ => abort_call_site!( - "Only option `Fields::Unnamed` or `Fields::Unit` is needed" - ), - } + ast_attrs.push("disable_strum_discriminants"); + } else if group.stream().to_string().contains("disable_back").clone() { + ast_attrs.push("disable_back"); }; } _ => (), //abort_call_site!("Only option `TokenTree::Group` is needed") @@ -57,85 +47,7 @@ pub fn fn_choose_variant( match attr_token { proc_macro2::TokenTree::Group(group) => { if &group.stream().to_string() == "derive(EnumMessage, EnumIter)" { - let doc_attrs = ast - .attrs - .iter() - .filter(|attr| attr.path.is_ident("doc".into())) - .map(|attr| { - let mut literal_string = String::new(); - for attr_token in attr.tokens.clone() { - match attr_token { - proc_macro2::TokenTree::Literal(literal) => { - literal_string = literal.to_string(); - } - _ => (), //abort_call_site!("Only option `TokenTree::Literal` is needed") - } - } - literal_string - }) - .collect::>(); - let literal_vec = doc_attrs - .iter() - .map(|s| s.replace("\"", "")) - .collect::>(); - let literal = - proc_macro2::Literal::string(literal_vec.join("\n ").as_str()); - - let enum_variants = variants.iter().map(|variant| { - let variant_ident = &variant.ident; - - match &variant.fields { - syn::Fields::Unnamed(_) => { - quote! { - #command_discriminants::#variant_ident => #cli_command::#variant_ident(Default::default()) - } - }, - syn::Fields::Unit => { - quote! { - #command_discriminants::#variant_ident => #cli_command::#variant_ident - } - }, - _ => abort_call_site!("Only option `Fields::Unnamed` or `Fields::Unit` is needed") - } - }); - - cli_variant = quote! { - use dialoguer::{theme::ColorfulTheme, Select}; - use strum::{EnumMessage, IntoEnumIterator}; - fn prompt_variant(prompt: &str) -> Option - where - T: IntoEnumIterator + EnumMessage, - T: Copy + Clone, - { - let variants = T::iter().collect::>(); - let mut actions = variants - .iter() - .map(|p| { - p.get_message() - .unwrap_or_else(|| "error[This entry does not have an option message!!]") - .to_owned() - }) - .collect::>(); - actions.push("back".to_string()); - - let selected = Select::with_theme(&ColorfulTheme::default()) - .with_prompt(prompt) - .items(&actions) - .default(0) - .interact() - .unwrap(); - - variants.get(selected).cloned() - }; - let variant = if let Some(variant) = prompt_variant(#literal.to_string().as_str()) { - variant - } else { - return Ok(None); - }; - let cli_variant = match variant { - #( #enum_variants, )* - }; - }; + ast_attrs.push("strum_discriminants"); }; } _ => (), //abort_call_site!("Only option `TokenTree::Group` is needed") @@ -143,6 +55,104 @@ pub fn fn_choose_variant( } }; } + if ast_attrs.contains(&"disable_strum_discriminants") { + match &variants[0].fields { + syn::Fields::Unnamed(_) => { + cli_variant = quote! { + let cli_variant = #cli_command::#variant_ident(Default::default()); + }; + } + syn::Fields::Unit => { + cli_variant = quote! { + let cli_variant = #cli_command::#variant_ident; + }; + } + _ => abort_call_site!("Only option `Fields::Unnamed` or `Fields::Unit` is needed"), + } + } else { + if ast_attrs.contains(&"disable_back") { + actions_push_back = quote!(); + } + if ast_attrs.contains(&"strum_discriminants") { + let doc_attrs = ast + .attrs + .iter() + .filter(|attr| attr.path.is_ident("doc".into())) + .map(|attr| { + let mut literal_string = String::new(); + for attr_token in attr.tokens.clone() { + match attr_token { + proc_macro2::TokenTree::Literal(literal) => { + literal_string = literal.to_string(); + } + _ => (), //abort_call_site!("Only option `TokenTree::Literal` is needed") + } + } + literal_string + }) + .collect::>(); + let literal_vec = doc_attrs + .iter() + .map(|s| s.replace("\"", "")) + .collect::>(); + let literal = proc_macro2::Literal::string(literal_vec.join("\n ").as_str()); + + let enum_variants = variants.iter().map(|variant| { + let variant_ident = &variant.ident; + + match &variant.fields { + syn::Fields::Unnamed(_) => { + quote! { + #command_discriminants::#variant_ident => #cli_command::#variant_ident(Default::default()) + } + }, + syn::Fields::Unit => { + quote! { + #command_discriminants::#variant_ident => #cli_command::#variant_ident + } + }, + _ => abort_call_site!("Only option `Fields::Unnamed` or `Fields::Unit` is needed") + } + }); + cli_variant = quote! { + use dialoguer::{theme::ColorfulTheme, Select}; + use strum::{EnumMessage, IntoEnumIterator}; + fn prompt_variant(prompt: &str) -> Option + where + T: IntoEnumIterator + EnumMessage, + T: Copy + Clone, + { + let variants = T::iter().collect::>(); + let mut actions = variants + .iter() + .map(|p| { + p.get_message() + .unwrap_or_else(|| "error[This entry does not have an option message!!]") + .to_owned() + }) + .collect::>(); + #actions_push_back; + + let selected = Select::with_theme(&ColorfulTheme::default()) + .with_prompt(prompt) + .items(&actions) + .default(0) + .interact() + .unwrap(); + + variants.get(selected).cloned() + }; + let variant = if let Some(variant) = prompt_variant(#literal.to_string().as_str()) { + variant + } else { + return Ok(None); + }; + let cli_variant = match variant { + #( #enum_variants, )* + }; + }; + } + } }; let input_context = interactive_clap_attrs_context.get_input_context_dir();