use crate::validation::Priority;
use clap::{Parser, Subcommand, ValueEnum, ValueHint};
#[derive(Parser, Debug)]
#[command(name = "askr")]
#[command(about = "Interactive CLI input tool with real-time validation and choice menus")]
#[command(version = env!("CARGO_PKG_VERSION"))]
#[command(
long_about = "Interactive CLI input tool with real-time validation and choice menus.
ENVIRONMENT VARIABLES:
ASKR_NO_COLOR Disable colored output (same as --no-color)
ASKR_WIDTH Set default display width in columns
ASKR_TIMEOUT Set default timeout in seconds
Example:
export ASKR_NO_COLOR=1
export ASKR_WIDTH=120
export ASKR_TIMEOUT=30
SHELL INTEGRATION EXAMPLES:
# Select from files in current directory
askr \"Select file:\" --choices \"$(ls -1)\"
# Pick from git branches
askr \"Switch to:\" --choices \"$(git branch --format='%(refname:short)')\"
# Git tags with space-delimited output
askr \"Select tags:\" --choices \"$(git tag)\" --selection-separator \" \" --min-choices 2
# Semicolon input, pipe output for modules
askr \"Pick modules:\" --choices \"auth;db;api;ui\" --choice-separator \";\" --selection-separator \" | \"
# Custom delimiters for file selection
askr \"Choose files:\" --choices \"$(find . -name '*.rs')\" --selection-separator \" \" --max-choices 5
# Specialized workflows with custom separators
askr \"Select options:\" --choices \"option1::option2::option3\" --choice-separator \"::\" --selection-separator \" + \""
)]
pub struct Args {
#[command(subcommand)]
pub command: Option<Commands>,
#[command(flatten)]
pub prompt_args: PromptArgs,
}
#[derive(Subcommand, Debug)]
pub enum Commands {
Completion {
#[arg(value_enum)]
shell: Shell,
},
}
#[derive(clap::ValueEnum, Clone, Debug)]
pub enum Shell {
Bash,
Zsh,
Fish,
PowerShell,
}
#[derive(Parser, Debug)]
pub struct PromptArgs {
pub prompt_text: Option<String>,
#[arg(long, value_enum, default_value = "default")]
pub output: OutputFormat,
#[arg(long)]
pub quiet: bool,
#[arg(long)]
pub verbose: bool,
#[arg(long)]
pub required: bool,
#[arg(long)]
pub max_length: Option<usize>,
#[arg(long)]
pub min_length: Option<usize>,
#[arg(long, value_hint = ValueHint::Other)]
pub pattern: Vec<String>,
#[arg(long)]
pub pattern_message: Vec<String>,
#[arg(long)]
pub validate_email: bool,
#[arg(long)]
pub validate_hostname: bool,
#[arg(long)]
pub validate_url: bool,
#[arg(long)]
pub validate_ipv4: bool,
#[arg(long)]
pub validate_ipv6: bool,
#[arg(long)]
pub number: bool,
#[arg(long)]
pub integer: bool,
#[arg(long)]
pub float: bool,
#[arg(long)]
pub range: Option<String>,
#[arg(long)]
pub positive: bool,
#[arg(long)]
pub negative: bool,
#[arg(long)]
pub date: bool,
#[arg(long, value_hint = ValueHint::Other)]
pub date_format: Option<String>,
#[arg(long)]
pub time: bool,
#[arg(long, value_hint = ValueHint::Other)]
pub time_format: Option<String>,
#[arg(long)]
pub datetime: bool,
#[arg(long, value_hint = ValueHint::Other)]
pub datetime_format: Option<String>,
#[arg(long)]
pub choices: Option<String>,
#[arg(long)]
pub choice_separator: Option<String>,
#[arg(long)]
pub selection_separator: Option<String>,
#[arg(long)]
pub choices_case_sensitive: bool,
#[arg(long)]
pub min_choices: Option<usize>,
#[arg(long)]
pub max_choices: Option<usize>,
#[arg(long)]
pub file_exists: bool,
#[arg(long)]
pub dir_exists: bool,
#[arg(long)]
pub path_exists: bool,
#[arg(long)]
pub readable: bool,
#[arg(long)]
pub writable: bool,
#[arg(long)]
pub executable: bool,
#[arg(long, value_enum)]
pub required_priority: Option<PriorityArg>,
#[arg(long, value_enum)]
pub length_priority: Option<PriorityArg>,
#[arg(long, value_enum)]
pub pattern_priority: Option<PriorityArg>,
#[arg(long, value_enum)]
pub format_priority: Option<PriorityArg>,
#[arg(long)]
pub max_attempts: Option<u32>,
#[arg(long)]
pub timeout: Option<u64>,
#[arg(long)]
pub default: Option<String>,
#[arg(long)]
pub mask: bool,
#[arg(long)]
pub confirm: bool,
#[arg(long)]
pub no_color: bool,
#[arg(long)]
pub width: Option<u16>,
#[arg(long)]
pub help_text: Option<String>,
}
#[derive(ValueEnum, Clone, Debug)]
pub enum OutputFormat {
Default,
Json,
Raw,
}
#[derive(ValueEnum, Clone, Debug)]
pub enum PriorityArg {
Critical,
High,
Medium,
Low,
}
impl From<PriorityArg> for Priority {
fn from(arg: PriorityArg) -> Self {
match arg {
PriorityArg::Critical => Priority::Critical,
PriorityArg::High => Priority::High,
PriorityArg::Medium => Priority::Medium,
PriorityArg::Low => Priority::Low,
}
}
}