diff options
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | src/vtcol.rs | 449 | 
2 files changed, 248 insertions, 203 deletions
@@ -5,7 +5,7 @@  [package]  name        = "vtcol"  description = "Set Linux console color scheme" -version     = "0.42.5" +version     = "0.42.6"  authors     = [ "Philipp Gesang <phg@phi-gamma.net>" ]  repository  = "https://github.com/phi-gamma/vtcol"  keywords    = [ "linux", "virtual_terminal", "tty", "console", "system" ] diff --git a/src/vtcol.rs b/src/vtcol.rs index 99846be..e9f9c2b 100644 --- a/src/vtcol.rs +++ b/src/vtcol.rs @@ -18,17 +18,17 @@ macro_rules! vrb {      )}  } -/* struct Job -- Runtime parameters. - */  #[derive(Debug)]  enum LedJob  { +    /** Get keyboard LED state. */      Get(bool), +    /** Set keyboard LED state. */      Set,  }  #[derive(Debug)] -enum Job +enum ColorJob  {      /** List available schemes. */      List, @@ -42,6 +42,14 @@ enum Job      Toggle(Scheme, Scheme),      /** Fade from current scheme to another. */      Fade(Option<Scheme>, Scheme, Duration, u8, bool), +} + +/** Subcommand and runtime parameters. */ +#[derive(Debug)] +enum Job +{ +    /** Console palette ops. */ +    Colors(ColorJob),      /** Keyboard LED ops. */      Leds(LedJob),  } @@ -56,127 +64,147 @@ impl<'a> Job              .version(clap::crate_version!())              .author(clap::crate_authors!())              .about(clap::crate_description!()) -            .subcommand( -                SubCommand::with_name("dump") -                    .about("dump a color scheme") -                    .arg( -                        Arg::with_name("scheme") -                            .help("name of the scheme") -                            .required(false) -                            .value_name("NAME") -                            .takes_value(true), -                    ) -                    .arg( -                        Arg::with_name("base64") -                            .short("b") -                            .long("base64") -                            .value_name("DATA") -                            .help("base64 encoded binary input") -                            .required(false) -                            .takes_value(true), -                    ), -            ) -            .subcommand( -                SubCommand::with_name("list").about("list builtin schemes"), -            ) -            .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("base64") -                            .short("b") -                            .long("base64") -                            .help("base64 encoded binary input") -                            .value_name("DATA") -                            .required(false) -                            .takes_value(true), -                    ), -            ) -            .subcommand( -                SubCommand::with_name("get") -                    .about("get current color scheme") -                    .arg( -                        Arg::with_name("base64") -                            .short("b") -                            .long("base64") -                            .help("base64 encoded binary output") -                            .required(false) -                            .takes_value(false), -                    ), +            .arg( +                Arg::with_name("verbose") +                    .short("v") +                    .long("verbose") +                    .help("enable extra diagnostics") +                    .takes_value(false),              )              .subcommand( -                SubCommand::with_name("toggle") -                    .about("toggle between two schemes") -                    .arg( -                        Arg::with_name("one") -                            .value_name("NAME1") -                            .help("predefined color scheme") -                            .takes_value(true), +                SubCommand::with_name("colors") +                    .about("operations on the console palette") +                    .subcommand( +                        SubCommand::with_name("dump") +                            .about("dump a color scheme") +                            .arg( +                                Arg::with_name("scheme") +                                    .help("name of the scheme") +                                    .required(false) +                                    .value_name("NAME") +                                    .takes_value(true), +                            ) +                            .arg( +                                Arg::with_name("base64") +                                    .short("b") +                                    .long("base64") +                                    .value_name("DATA") +                                    .help("base64 encoded binary input") +                                    .required(false) +                                    .takes_value(true), +                            ),                      ) -                    .arg( -                        Arg::with_name("two") -                            .value_name("NAME2") -                            .help("predefined color scheme") -                            .takes_value(true), -                    ), -            ) -            .subcommand( -                SubCommand::with_name("fade") -                    .about("fade from one scheme to another") -                    .arg( -                        Arg::with_name("from") -                            .short("f") -                            .long("from") -                            .value_name("NAME1") -                            .help("initial color scheme (default: current)") -                            .takes_value(true), +                    .subcommand( +                        SubCommand::with_name("list") +                            .about("list builtin schemes"),                      ) -                    .arg( -                        Arg::with_name("to") -                            .short("t") -                            .long("to") -                            .value_name("NAME2") -                            .help("final color scheme") -                            .takes_value(true) -                            .required(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("base64") +                                    .short("b") +                                    .long("base64") +                                    .help("base64 encoded binary input") +                                    .value_name("DATA") +                                    .required(false) +                                    .takes_value(true), +                            ),                      ) -                    .arg( -                        Arg::with_name("ms") -                            .value_name("MS") -                            .short("m") -                            .long("ms") -                            .help("how long (in ms) the fade should take") -                            .takes_value(true), +                    .subcommand( +                        SubCommand::with_name("get") +                            .about("get current color scheme") +                            .arg( +                                Arg::with_name("base64") +                                    .short("b") +                                    .long("base64") +                                    .help("base64 encoded binary output") +                                    .required(false) +                                    .takes_value(false), +                            ),                      ) -                    .arg( -                        Arg::with_name("clear") -                            .short("c") -                            .long("clear") -                            .help("clear terminal on each fade step") -                            .takes_value(false), +                    .subcommand( +                        SubCommand::with_name("toggle") +                            .about("toggle between two schemes") +                            .arg( +                                Arg::with_name("one") +                                    .value_name("NAME1") +                                    .help("predefined color scheme") +                                    .takes_value(true), +                            ) +                            .arg( +                                Arg::with_name("two") +                                    .value_name("NAME2") +                                    .help("predefined color scheme") +                                    .takes_value(true), +                            ),                      ) -                    .arg( -                        Arg::with_name("frequency") -                            .value_name("HZ") -                            .short("h") -                            .long("frequency") -                            .help("rate (HZ/s) of intermediate scheme changes") -                            .takes_value(true), +                    .subcommand( +                        SubCommand::with_name("fade") +                            .about("fade from one scheme to another") +                            .arg( +                                Arg::with_name("from") +                                    .short("f") +                                    .long("from") +                                    .value_name("NAME1") +                                    .help( +                                        "initial color scheme (default: \ +                                         current)", +                                    ) +                                    .takes_value(true), +                            ) +                            .arg( +                                Arg::with_name("to") +                                    .short("t") +                                    .long("to") +                                    .value_name("NAME2") +                                    .help("final color scheme") +                                    .takes_value(true) +                                    .required(true), +                            ) +                            .arg( +                                Arg::with_name("ms") +                                    .value_name("MS") +                                    .short("m") +                                    .long("ms") +                                    .help( +                                        "how long (in ms) the fade should take", +                                    ) +                                    .takes_value(true), +                            ) +                            .arg( +                                Arg::with_name("clear") +                                    .short("c") +                                    .long("clear") +                                    .help("clear terminal on each fade step") +                                    .takes_value(false), +                            ) +                            .arg( +                                Arg::with_name("frequency") +                                    .value_name("HZ") +                                    .short("h") +                                    .long("frequency") +                                    .help( +                                        "rate (HZ/s) of intermediate scheme \ +                                         changes", +                                    ) +                                    .takes_value(true), +                            ),                      ),              )              .subcommand( @@ -194,13 +222,6 @@ impl<'a> Job                                      .takes_value(false),                              ),                      ), -            ) -            .arg( -                Arg::with_name("verbose") -                    .short("v") -                    .long("verbose") -                    .help("enable extra diagnostics") -                    .takes_value(false),              );          let matches = app.get_matches(); @@ -210,83 +231,105 @@ impl<'a> Job          }          match matches.subcommand() { -            ("dump", Some(subm)) => { -                if let Some(b64) = subm.value_of("base64") { -                    let scheme = Scheme::from_base64(b64)?; -                    return Ok(Self::Dump(scheme)); -                } -                if let Some(name) = subm.value_of("scheme") { -                    let scm = Scheme::from(name); -                    return Ok(Self::Dump(scm)); -                } -                Err(anyhow!("dump requires an argument")) -            }, -            ("list", _) => Ok(Self::List), -            ("set", Some(subm)) => { -                if let Some(b64) = subm.value_of("base64") { -                    let scheme = Scheme::from_base64(&b64)?; -                    return Ok(Self::Set(scheme)); -                } -                let scheme = match subm.value_of("scheme") { -                    Some("-") => Self::read_scheme_from_stdin(), -                    Some(name) => { -                        vrb!("pick predefined scheme [{}]", name); -                        Scheme::from(name) +            ("colors", Some(subm)) => +                match subm.subcommand() { +                    ("dump", Some(subm)) => { +                        if let Some(b64) = subm.value_of("base64") { +                            let scheme = Scheme::from_base64(b64)?; +                            return Ok(Self::Colors(ColorJob::Dump(scheme))); +                        } +                        if let Some(name) = subm.value_of("scheme") { +                            let scm = Scheme::from(name); +                            return Ok(Self::Colors(ColorJob::Dump(scm))); +                        } +                        Err(anyhow!("dump requires an argument")) +                    }, +                    ("list", _) => Ok(Self::Colors(ColorJob::List)), +                    ("set", Some(subm)) => { +                        if let Some(b64) = subm.value_of("base64") { +                            let scheme = Scheme::from_base64(&b64)?; +                            return Ok(Self::Colors(ColorJob::Set(scheme))); +                        } +                        let scheme = match subm.value_of("scheme") { +                            Some("-") => Self::read_scheme_from_stdin(), +                            Some(name) => { +                                vrb!("pick predefined scheme [{}]", name); +                                Scheme::from(name) +                            }, +                            None => +                                match subm.value_of("file") { +                                    None | Some("-") => +                                        Self::read_scheme_from_stdin(), +                                    Some(fname) => { +                                        vrb!( +                                            "read custom scheme from file [{}]", +                                            fname +                                        ); +                                        Scheme::from_path(fname) +                                    }, +                                }, +                        }; +                        Ok(Self::Colors(ColorJob::Set(scheme)))                      }, -                    None => -                        match subm.value_of("file") { -                            None | Some("-") => Self::read_scheme_from_stdin(), -                            Some(fname) => { -                                vrb!( -                                    "read custom scheme from file [{}]", -                                    fname -                                ); -                                Scheme::from_path(fname) +                    ("get", Some(subm)) => +                        Ok(Self::Colors(ColorJob::Get( +                            subm.is_present("base64"), +                        ))), +                    ("toggle", Some(subm)) => { +                        match (subm.value_of("one"), subm.value_of("two")) { +                            (Some(one), Some(two)) => { +                                vrb!("toggle schemes [{}] and [{}]", one, two); +                                Ok(Self::Colors(ColorJob::Toggle( +                                    Scheme::from(one), +                                    Scheme::from(two), +                                )))                              }, -                        }, -                }; -                Ok(Self::Set(scheme)) -            }, -            ("get", Some(subm)) => Ok(Self::Get(subm.is_present("base64"))), -            ("toggle", Some(subm)) => { -                match (subm.value_of("one"), subm.value_of("two")) { -                    (Some(one), Some(two)) => { -                        vrb!("toggle schemes [{}] and [{}]", one, two); -                        Ok(Self::Toggle(Scheme::from(one), Scheme::from(two))) +                            _ => +                                Err(anyhow!( +                                    "please supply two schemes to toggle \ +                                     between" +                                )), +                        } +                    }, +                    ("fade", Some(subm)) => { +                        let dur: u64 = if let Some(ms) = subm.value_of("ms") { +                            ms.parse()? +                        } else { +                            DEFAULT_FADE_DURATION_MS +                        }; +                        let hz: u8 = +                            if let Some(ms) = subm.value_of("frequency") { +                                ms.parse()? +                            } else { +                                DEFAULT_FADE_UPDATE_HZ +                            }; +                        let clear = subm.is_present("clear"); +                        let dur = Duration::from_millis(dur); + +                        match (subm.value_of("from"), subm.value_of("to")) { +                            (_, None) => +                                Err(anyhow!( +                                    "please supply color scheme to fade to" +                                )), +                            (from, Some(to)) => +                                Ok(Self::Colors(ColorJob::Fade( +                                    from.map(Scheme::from), +                                    Scheme::from(to), +                                    dur, +                                    hz, +                                    clear, +                                ))), +                        }                      }, -                    _ => +                    (junk, _) =>                          Err(anyhow!( -                            "please supply two schemes to toggle between" -                        )), -                } -            }, -            ("fade", Some(subm)) => { -                let dur: u64 = if let Some(ms) = subm.value_of("ms") { -                    ms.parse()? -                } else { -                    DEFAULT_FADE_DURATION_MS -                }; -                let hz: u8 = if let Some(ms) = subm.value_of("frequency") { -                    ms.parse()? -                } else { -                    DEFAULT_FADE_UPDATE_HZ -                }; -                let clear = subm.is_present("clear"); -                let dur = Duration::from_millis(dur); - -                match (subm.value_of("from"), subm.value_of("to")) { -                    (_, None) => -                        Err(anyhow!("please supply color scheme to fade to")), -                    (from, Some(to)) => -                        Ok(Self::Fade( -                            from.map(Scheme::from), -                            Scheme::from(to), -                            dur, -                            hz, -                            clear, +                            "invalid sub-subcommand to colors: [{}]; try ``{} \ +                             colors --help``", +                            junk, +                            clap::crate_name!()                          )), -                } -            }, +                }, +              ("leds", Some(subm)) =>                  match subm.subcommand() {                      ("get", Some(subm)) => { @@ -301,6 +344,7 @@ impl<'a> Job                              clap::crate_name!()                          )),                  }, +              (junk, _) =>                  Err(anyhow!(                      "invalid subcommand [{}]; try ``{} --help``", @@ -360,12 +404,13 @@ impl<'a> Job      fn run(self) -> Result<()>      {          match self { -            Self::Dump(scm) => Self::dump(scm)?, -            Self::List => Self::list_schemes(), -            Self::Set(scm) => Self::set_scheme(scm)?, -            Self::Get(b64) => Self::get_scheme(b64)?, -            Self::Toggle(one, two) => Self::toggle_scheme(one, two)?, -            Self::Fade(from, to, ms, hz, clear) => +            Self::Colors(ColorJob::Dump(scm)) => Self::dump(scm)?, +            Self::Colors(ColorJob::List) => Self::list_schemes(), +            Self::Colors(ColorJob::Set(scm)) => Self::set_scheme(scm)?, +            Self::Colors(ColorJob::Get(b64)) => Self::get_scheme(b64)?, +            Self::Colors(ColorJob::Toggle(one, two)) => +                Self::toggle_scheme(one, two)?, +            Self::Colors(ColorJob::Fade(from, to, ms, hz, clear)) =>                  Self::fade(from, to, ms, hz, clear)?,              Self::Leds(LedJob::Get(raw)) => Self::get_leds(raw)?,              Self::Leds(LedJob::Set) => unimplemented!(),  | 
