use clap;
use inquire::{set_global_render_config, Select};
use interactive_clap::{ResultFromCli, ToCliArgs};
use shell_words;
use strum::{EnumDiscriminants, EnumIter, EnumMessage, IntoEnumIterator};
#[derive(Debug, Clone, interactive_clap::InteractiveClap)]
struct Args {
#[interactive_clap(long = "age-full-years")]
#[interactive_clap(skip_interactive_input)]
age: Option<u64>,
#[interactive_clap(long)]
first_name: String,
#[interactive_clap(long)]
#[interactive_clap(skip_default_input_arg)]
second_name: String,
#[interactive_clap(long)]
#[interactive_clap(value_enum)]
#[interactive_clap(skip_default_input_arg)]
favorite_color: ColorPalette,
}
impl Args {
fn input_second_name(_context: &()) -> color_eyre::eyre::Result<Option<String>> {
match inquire::Text::new("Input second name".to_string().as_str()).prompt() {
Ok(value) => Ok(Some(value)),
Err(
inquire::error::InquireError::OperationCanceled
| inquire::error::InquireError::OperationInterrupted,
) => Ok(None),
Err(err) => Err(err.into()),
}
}
fn input_favorite_color(_context: &()) -> color_eyre::eyre::Result<Option<ColorPalette>> {
let variants = ColorPaletteDiscriminants::iter().collect::<Vec<_>>();
let selected = Select::new("What color is your favorite?", variants).prompt()?;
match selected {
ColorPaletteDiscriminants::Red => Ok(Some(ColorPalette::Red)),
ColorPaletteDiscriminants::Orange => Ok(Some(ColorPalette::Orange)),
ColorPaletteDiscriminants::Yellow => Ok(Some(ColorPalette::Yellow)),
ColorPaletteDiscriminants::Green => Ok(Some(ColorPalette::Green)),
ColorPaletteDiscriminants::Blue => Ok(Some(ColorPalette::Blue)),
ColorPaletteDiscriminants::Indigo => Ok(Some(ColorPalette::Indigo)),
ColorPaletteDiscriminants::Violet => Ok(Some(ColorPalette::Violet)),
}
}
}
#[derive(Debug, EnumDiscriminants, Clone, clap::ValueEnum)]
#[strum_discriminants(derive(EnumMessage, EnumIter))]
pub enum ColorPalette {
#[strum_discriminants(strum(message = "red"))]
Red,
#[strum_discriminants(strum(message = "orange"))]
Orange,
#[strum_discriminants(strum(message = "yellow"))]
Yellow,
#[strum_discriminants(strum(message = "green"))]
Green,
#[strum_discriminants(strum(message = "blue"))]
Blue,
#[strum_discriminants(strum(message = "indigo"))]
Indigo,
#[strum_discriminants(strum(message = "violet"))]
Violet,
}
impl interactive_clap::ToCli for ColorPalette {
type CliVariant = ColorPalette;
}
impl std::str::FromStr for ColorPalette {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"red" => Ok(Self::Red),
"orange" => Ok(Self::Orange),
"yellow" => Ok(Self::Yellow),
"green" => Ok(Self::Green),
"blue" => Ok(Self::Blue),
"indigo" => Ok(Self::Indigo),
"violet" => Ok(Self::Violet),
_ => Err("ColorPalette: incorrect value entered".to_string()),
}
}
}
impl std::fmt::Display for ColorPalette {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::Red => write!(f, "red"),
Self::Orange => write!(f, "orange"),
Self::Yellow => write!(f, "yellow"),
Self::Green => write!(f, "green"),
Self::Blue => write!(f, "blue"),
Self::Indigo => write!(f, "indigo"),
Self::Violet => write!(f, "violet"),
}
}
}
impl std::fmt::Display for ColorPaletteDiscriminants {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::Red => write!(f, "red"),
Self::Orange => write!(f, "orange"),
Self::Yellow => write!(f, "yellow"),
Self::Green => write!(f, "green"),
Self::Blue => write!(f, "blue"),
Self::Indigo => write!(f, "indigo"),
Self::Violet => write!(f, "violet"),
}
}
}
fn main() -> color_eyre::Result<()> {
set_global_render_config(thag_styling::themed_inquire_config());
let mut cli_args = Args::parse();
let context = (); loop {
let args = <Args as interactive_clap::FromCli>::from_cli(Some(cli_args), context);
match args {
ResultFromCli::Ok(cli_args) | ResultFromCli::Cancel(Some(cli_args)) => {
println!("cli_args: {cli_args:?}");
println!(
"Your console command: {}",
shell_words::join(&cli_args.to_cli_args())
);
return Ok(());
}
ResultFromCli::Cancel(None) => {
println!("Goodbye!");
return Ok(());
}
ResultFromCli::Back => {
cli_args = Default::default();
}
ResultFromCli::Err(cli_args, err) => {
if let Some(cli_args) = cli_args {
println!(
"Your console command: {}",
shell_words::join(&cli_args.to_cli_args())
);
}
return Err(err);
}
}
}
}