From b9797074f5780d2640539db26142fcc79bada3b1 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Wed, 10 Nov 2021 21:42:21 +0100 Subject: adopt a subcommand ui Regroup the cli arguments into subcommands: $ vtcol dump $SCHEME $ vtcol list $ vtcol set $SCHEME --- src/vtcol.rs | 150 +++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 90 insertions(+), 60 deletions(-) diff --git a/src/vtcol.rs b/src/vtcol.rs index d886f2b..a007185 100644 --- a/src/vtcol.rs +++ b/src/vtcol.rs @@ -126,6 +126,31 @@ impl<'a> fmt::Display for Scheme } } /* [impl fmt::String for Scheme] */ +impl Scheme +{ + fn from_stdin() -> Self { Self::Custom(None) } + + fn from_path>(path: P) -> Self + { + Self::Custom(Some(path.as_ref().into())) + } +} /* [impl Scheme] */ + +/** Try to select one of the predefined schemes; if that fails, +interpret the argument as a path. */ +impl From<&str> for Scheme +{ + fn from(name: &str) -> Scheme + { + match name { + "solarized" | "solarized_dark" | "sd" => Self::SolarizedDark, + "solarized_light" | "sl" => Self::SolarizedLight, + "default" | "normal" => Self::Default, + path => Self::from_path(path), + } + } +} + /* struct Job -- Runtime parameters. */ #[derive(Debug)] @@ -143,35 +168,42 @@ impl<'a> Job { pub fn from_argv() -> Result { - use clap::{App, Arg}; + use clap::{App, Arg, SubCommand}; let app = App::new(clap::crate_name!()) .version(clap::crate_version!()) .author(clap::crate_authors!()) .about(clap::crate_description!()) - .arg( - Arg::with_name("scheme") - .short("s") - .long("scheme") - .value_name("NAME") - .help("predefined color scheme") - .takes_value(true), + .subcommand( + SubCommand::with_name("dump").about("dump a color scheme").arg( + Arg::with_name("scheme") + .help("name of the scheme") + .required(true) + .value_name("NAME") + .index(1), + ), ) - .arg( - Arg::with_name("dump") - .short("d") - .long("dump") - .value_name("NAME") - .help("dump predefined scheme") - .takes_value(true), + .subcommand( + SubCommand::with_name("list").about("list available schemes"), ) - .arg( - Arg::with_name("file") - .short("f") - .long("file") - .value_name("PATH") - .help("apply scheme from file") - .takes_value(true), + .subcommand( + SubCommand::with_name("set") + .about("apply color scheme to current terminal") + .arg( + Arg::with_name("scheme") + .value_name("NAME") + .help("predefined color scheme") + .takes_value(true) + .conflicts_with("file"), + ) + .arg( + Arg::with_name("file") + .short("f") + .long("file") + .value_name("PATH") + .help("apply scheme from file") + .takes_value(true), + ), ) .arg( Arg::with_name("verbose") @@ -179,13 +211,6 @@ impl<'a> Job .long("verbose") .help("enable extra diagnostics") .takes_value(false), - ) - .arg( - Arg::with_name("list") - .short("l") - .long("list") - .help("list available color schemes") - .takes_value(false), ); let matches = app.get_matches(); @@ -194,40 +219,45 @@ impl<'a> Job VERBOSITY.store(true, Ordering::SeqCst); } - if matches.is_present("list") { - return Ok(Self::List); - }; - - if let Some(name) = matches.value_of("dump") { - let scm = Self::pick_scheme(name); - return Ok(Self::Dump(scm)); - } - - let scheme = match matches.value_of("file") { - Some("-") => Self::scheme_from_stdin(), - Some(fname) => Scheme::Custom(Some(PathBuf::from(fname))), - None => - match matches.value_of("scheme") { - Some("-") | None => Self::scheme_from_stdin(), - Some(name) => Self::pick_scheme(name), - }, - }; - - Ok(Self::Set(scheme)) - } - - fn pick_scheme(name: &str) -> Scheme - { - match name { - "solarized" | "solarized_dark" | "sd" => Scheme::SolarizedDark, - "solarized_light" | "sl" => Scheme::SolarizedLight, - "default" | "normal" => Scheme::Default, - _any => Scheme::Custom(Some(PathBuf::from(name))), + match matches.subcommand() { + ("dump", Some(subm)) => { + if let Some(name) = subm.value_of("name") { + let scm = Scheme::from(name); + return Ok(Self::Dump(scm)); + } + Err(anyhow!("dump requires an argument")) + }, + ("list", _) => Ok(Self::List), + ("set", Some(subm)) => { + let scheme = match subm.value_of("scheme") { + Some("-") => Scheme::from_stdin(), + Some(name) => { + vrb!("pick predefined scheme [{}]", name); + Scheme::from(name) + }, + None => + match subm.value_of("file") { + None | Some("-") => Scheme::from_stdin(), + Some(fname) => { + vrb!( + "read custom scheme from file [{}]", + fname + ); + Scheme::from_path(fname) + }, + }, + }; + Ok(Self::Set(scheme)) + }, + (junk, _) => + Err(anyhow!( + "invalid subcommand [{}]; try “{} --help”", + junk, + clap::crate_name!() + )), } } - fn scheme_from_stdin() -> Scheme { Scheme::Custom(None) } - fn schemes() { println!("Available color schemes:"); -- cgit v1.2.3