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,
Dashboard {
#[arg(long)]
host: bool,
#[arg(long, short, default_value_t = 7822)]
port: u16,
#[arg(long)]
no_open: bool,
},
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 dashboard_subcommand_defaults() {
let cli = Cli::parse_from(["audiorouter", "dashboard"]);
assert_eq!(
cli.command_or_default(),
Command::Dashboard {
host: false,
port: 7822,
no_open: false,
}
);
}
#[test]
fn dashboard_no_open_flag() {
let cli = Cli::parse_from(["audiorouter", "dashboard", "--no-open"]);
assert_eq!(
cli.command_or_default(),
Command::Dashboard {
host: false,
port: 7822,
no_open: true,
}
);
}
#[test]
fn dashboard_host_and_port_flags() {
let cli = Cli::parse_from([
"audiorouter",
"dashboard",
"--host",
"--port",
"9000",
"--no-open",
]);
assert_eq!(
cli.command_or_default(),
Command::Dashboard {
host: true,
port: 9000,
no_open: true,
}
);
}
#[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);
}
}