use std::path::PathBuf;
use clap::{Parser, Subcommand};
#[derive(Debug, Parser)]
#[command(version, about, long_about = None)]
pub struct Cli {
#[arg(short, long, global = true)]
pub config: Option<PathBuf>,
#[arg(short, long, global = true)]
pub quiet: bool,
#[arg(short, long, global = true, action = clap::ArgAction::Count)]
pub verbose: u8,
#[command(subcommand)]
pub command: Option<Command>,
}
#[derive(Debug, Clone, PartialEq, Eq, Subcommand)]
pub enum Command {
Run,
Check,
ListDevices,
ConfigPath,
Completions {
shell: Option<clap_complete::Shell>,
#[arg(short, long)]
output: Option<std::path::PathBuf>,
},
}
impl Cli {
pub fn command_or_default(&self) -> Command {
self.command.clone().unwrap_or(Command::Run)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn no_subcommand_is_run() {
let cli = Cli::parse_from(["audiorouter"]);
assert_eq!(cli.command_or_default(), Command::Run);
}
#[test]
fn run_subcommand() {
let cli = Cli::parse_from(["audiorouter", "run"]);
assert_eq!(cli.command_or_default(), Command::Run);
}
#[test]
fn check_subcommand() {
let cli = Cli::parse_from(["audiorouter", "check"]);
assert_eq!(cli.command_or_default(), Command::Check);
}
#[test]
fn list_devices_subcommand() {
let cli = Cli::parse_from(["audiorouter", "list-devices"]);
assert_eq!(cli.command_or_default(), Command::ListDevices);
}
#[test]
fn config_path_subcommand() {
let cli = Cli::parse_from(["audiorouter", "config-path"]);
assert_eq!(cli.command_or_default(), Command::ConfigPath);
}
#[test]
fn config_flag_before_subcommand() {
let cli = Cli::parse_from(["audiorouter", "-c", "cfg.toml", "check"]);
assert_eq!(cli.command_or_default(), Command::Check);
assert_eq!(cli.config, Some(PathBuf::from("cfg.toml")));
}
#[test]
fn config_flag_after_subcommand() {
let cli = Cli::parse_from(["audiorouter", "check", "-c", "cfg.toml"]);
assert_eq!(cli.command_or_default(), Command::Check);
assert_eq!(cli.config, Some(PathBuf::from("cfg.toml")));
}
#[test]
fn config_flag_without_subcommand() {
let cli = Cli::parse_from(["audiorouter", "-c", "cfg.toml"]);
assert_eq!(cli.command_or_default(), Command::Run);
assert_eq!(cli.config, Some(PathBuf::from("cfg.toml")));
}
#[test]
fn quiet_flag() {
let cli = Cli::parse_from(["audiorouter", "--quiet", "run"]);
assert!(cli.quiet);
}
#[test]
fn verbose_flags() {
let cli = Cli::parse_from(["audiorouter", "-vv", "run"]);
assert_eq!(cli.verbose, 2);
}
}