added "disable_back" to enums

This commit is contained in:
FroVolod
2022-09-06 11:46:45 +03:00
committed by FroVolod
parent 97c6193e78
commit 820f1d7e0c
@@ -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::<Vec<_>>();
let literal_vec = doc_attrs
.iter()
.map(|s| s.replace("\"", ""))
.collect::<Vec<_>>();
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<T>(prompt: &str) -> Option<T>
where
T: IntoEnumIterator + EnumMessage,
T: Copy + Clone,
{
let variants = T::iter().collect::<Vec<_>>();
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::<Vec<_>>();
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::<Vec<_>>();
let literal_vec = doc_attrs
.iter()
.map(|s| s.replace("\"", ""))
.collect::<Vec<_>>();
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<T>(prompt: &str) -> Option<T>
where
T: IntoEnumIterator + EnumMessage,
T: Copy + Clone,
{
let variants = T::iter().collect::<Vec<_>>();
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::<Vec<_>>();
#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();