diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/vtcol.rs | 410 |
1 files changed, 222 insertions, 188 deletions
diff --git a/src/vtcol.rs b/src/vtcol.rs index 0daccb0..3578986 100644 --- a/src/vtcol.rs +++ b/src/vtcol.rs @@ -18,6 +18,11 @@ macro_rules! vrb { )} } +trait Run +{ + fn run(self) -> Result<()>; +} + #[derive(Debug)] enum LedJob { @@ -31,6 +36,85 @@ enum LedJob SetIndividual(Option<bool>, Option<bool>, Option<bool>), } +impl Run for LedJob +{ + fn run(self) -> Result<()> + { + match self { + Self::Get(raw) => Self::get(raw), + Self::Revert => Self::revert(), + Self::Set(st) => Self::set(st), + Self::SetIndividual(c, n, s) => Self::set_individual(c, n, s), + } + } +} /* [impl Run for LedJob] */ + +impl LedJob +{ + /** Get the keyboard LED state. */ + fn get(raw: bool) -> Result<()> + { + let fd = Console::current()?; + vrb!("console fd: {}", fd); + + let leds = KbLedState::get(&fd)?; + + if raw { + println!("{}", u8::from(leds)); + } else { + println!("{}", leds); + } + + Ok(()) + } + + /** Set the keyboard LED state. */ + fn set(st: KbLedState) -> Result<()> + { + let fd = Console::current()?; + vrb!("console fd: {}", fd); + + st.set(&fd)?; + vrb!("applied"); + + Ok(()) + } + + /** Set the state of the given LEDs using the current state as base. */ + fn set_individual( + cap: Option<bool>, + num: Option<bool>, + scr: Option<bool>, + ) -> Result<()> + { + let fd = Console::current()?; + vrb!("console fd: {}", fd); + + let mut st = KbLedState::get(&fd)?; + + cap.map(|b| st.set_cap(b)); + num.map(|b| st.set_num(b)); + scr.map(|b| st.set_scr(b)); + + st.set(&fd)?; + vrb!("applied"); + + Ok(()) + } + + /** Revert the keyboard LED state. */ + fn revert() -> Result<()> + { + let fd = Console::current()?; + vrb!("console fd: {}", fd); + + KbLedState::revert(&fd)?; + vrb!("reverted"); + + Ok(()) + } +} /* [impl LedJob] */ + #[derive(Debug)] enum ColorJob { @@ -48,6 +132,138 @@ enum ColorJob Fade(Option<Scheme>, Scheme, Duration, u8, bool), } +impl Run for ColorJob +{ + fn run(self) -> Result<()> + { + match self { + Self::Dump(scm) => Self::dump(scm), + Self::List => Self::list(), + Self::Set(scm) => Self::set(scm), + Self::Get(b64) => Self::get(b64), + Self::Toggle(one, two) => Self::toggle(one, two), + Self::Fade(from, to, ms, hz, clear) => + Self::fade(from, to, ms, hz, clear), + } + } +} /* [impl Run for ColorJob] */ + +impl ColorJob +{ + fn list() -> Result<()> + { + println!("{} color schemes available:", vtcol::BUILTIN_SCHEMES.len()); + for s in vtcol::BUILTIN_SCHEMES { + println!(" * {}", s.name()); + } + + Ok(()) + } + + fn dump(scm: Scheme) -> Result<()> + { + vrb!("Dumping color scheme {}", scm); + let mut out = BufWriter::new(io::stdout()); + + match scm { + Scheme::Builtin(bltn) => + Palette::from(bltn.palette()).dump(&mut out).map_err(|e| { + anyhow!( + "error loading builtin scheme {}: {}", + bltn.name(), + e + ) + }), + Scheme::Custom(None) => + Palette::from_stdin()?.dump(&mut out).map_err(|e| { + anyhow!("error loading palette from stdin: {}", e) + }), + Scheme::Custom(Some(fname)) => + Palette::from_file(&fname)?.dump(&mut out).map_err(|e| { + anyhow!( + "error loading palette from file [{}]: {}", + fname.display(), + e + ) + }), + Scheme::Palette(pal) => + pal.dump(&mut out) + .map_err(|e| anyhow!("error dumping palette: {}", e)), + } + } + + fn set(scheme: Scheme) -> Result<()> + { + let con = Console::current()?; + vrb!("console fd: {}", con); + + con.apply_scheme(&scheme)?; + con.clear()?; + + vrb!("successfully enabled scheme {:?}", scheme); + /* It’s fine to leak the fd, the kernel will clean up anyways. */ + Ok(()) + } + + fn get(b64: bool) -> Result<()> + { + let fd = Console::current()?; + vrb!("console fd: {}", fd); + + let scm = fd.current_scheme()?; + if b64 { + print!("{}", scm.base64()?); + } else { + vrb!("active scheme:"); + println!("{}", scm); + } + + Ok(()) + } + + /** Toggle between two schemes. Defaults to ``one`` in case neither scheme + is active. + */ + fn toggle(one: Scheme, two: Scheme) -> Result<()> + { + let fd = Console::current()?; + vrb!("console fd: {}", fd); + + if fd.current_palette()? == Palette::try_from(&one)? { + Self::set(two) + } else { + Self::set(one) + } + } + + /** Fade from one scheme to another. + + If ``from`` is ``None``, the current palette is used as starting point. */ + fn fade( + from: Option<Scheme>, + to: Scheme, + dur: Duration, + hz: u8, + clear: bool, + ) -> Result<()> + { + let fd = Console::current()?; + vrb!("console fd: {}", fd); + + let from = if let Some(from) = from { + Palette::try_from(&from)? + } else { + fd.current_palette()? + }; + let to = Palette::try_from(&to)?; + + let fade = Fade::new(from, to, dur, hz, clear); + + fade.commence(&fd)?; + Ok(()) + } +} /* [impl ColorJob] */ + /** Subcommand and runtime parameters. */ #[derive(Debug)] enum Job @@ -429,208 +645,26 @@ impl<'a> Job } } - fn list_schemes() - { - println!("{} color schemes available:", vtcol::BUILTIN_SCHEMES.len()); - for s in vtcol::BUILTIN_SCHEMES { - println!(" * {}", s.name()); - } - } - fn read_scheme_from_stdin() -> Scheme { vrb!("Go ahead, type your color scheme …"); vrb!("vtcol>"); Scheme::from_stdin() } +} /* [impl Job] */ - fn dump(scm: Scheme) -> Result<()> - { - vrb!("Dumping color scheme {}", scm); - let mut out = BufWriter::new(io::stdout()); - - match scm { - Scheme::Builtin(bltn) => - Palette::from(bltn.palette()).dump(&mut out).map_err(|e| { - anyhow!( - "error loading builtin scheme {}: {}", - bltn.name(), - e - ) - }), - Scheme::Custom(None) => - Palette::from_stdin()?.dump(&mut out).map_err(|e| { - anyhow!("error loading palette from stdin: {}", e) - }), - Scheme::Custom(Some(fname)) => - Palette::from_file(&fname)?.dump(&mut out).map_err(|e| { - anyhow!( - "error loading palette from file [{}]: {}", - fname.display(), - e - ) - }), - Scheme::Palette(pal) => - pal.dump(&mut out) - .map_err(|e| anyhow!("error dumping palette: {}", e)), - } - } - +impl Run for Job +{ fn run(self) -> Result<()> { match self { - 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::Revert) => Self::revert_leds()?, - Self::Leds(LedJob::Set(st)) => Self::set_leds(st)?, - Self::Leds(LedJob::SetIndividual(c, n, s)) => - Self::set_leds_individual(c, n, s)?, - } - - Ok(()) - } - - fn set_scheme(scheme: Scheme) -> Result<()> - { - let con = Console::current()?; - vrb!("console fd: {}", con); - - con.apply_scheme(&scheme)?; - con.clear()?; - - vrb!("successfully enabled scheme {:?}", scheme); - /* It’s fine to leak the fd, the kernel will clean up anyways. */ - Ok(()) - } - - fn get_scheme(b64: bool) -> Result<()> - { - let fd = Console::current()?; - vrb!("console fd: {}", fd); - - let scm = fd.current_scheme()?; - if b64 { - print!("{}", scm.base64()?); - } else { - vrb!("active scheme:"); - println!("{}", scm); - } - - Ok(()) - } - - /** Toggle between two schemes. Defaults to ``one`` in case neither scheme - is active. - */ - fn toggle_scheme(one: Scheme, two: Scheme) -> Result<()> - { - let fd = Console::current()?; - vrb!("console fd: {}", fd); - - if fd.current_palette()? == Palette::try_from(&one)? { - Self::set_scheme(two) - } else { - Self::set_scheme(one) - } - } - - /** Fade from one scheme to another. - - If ``from`` is ``None``, the current palette is used as starting point. */ - fn fade( - from: Option<Scheme>, - to: Scheme, - dur: Duration, - hz: u8, - clear: bool, - ) -> Result<()> - { - let fd = Console::current()?; - vrb!("console fd: {}", fd); - - let from = if let Some(from) = from { - Palette::try_from(&from)? - } else { - fd.current_palette()? - }; - let to = Palette::try_from(&to)?; - - let fade = Fade::new(from, to, dur, hz, clear); - - fade.commence(&fd)?; - Ok(()) - } - - /** Get the keyboard LED state. */ - fn get_leds(raw: bool) -> Result<()> - { - let fd = Console::current()?; - vrb!("console fd: {}", fd); - - let leds = KbLedState::get(&fd)?; - - if raw { - println!("{}", u8::from(leds)); - } else { - println!("{}", leds); + Self::Colors(cols) => cols.run()?, + Self::Leds(leds) => leds.run()?, } Ok(()) } - - /** Set the keyboard LED state. */ - fn set_leds(st: KbLedState) -> Result<()> - { - let fd = Console::current()?; - vrb!("console fd: {}", fd); - - st.set(&fd)?; - vrb!("applied"); - - Ok(()) - } - - /** Set the state of the given LEDs using the current state as base. */ - fn set_leds_individual( - cap: Option<bool>, - num: Option<bool>, - scr: Option<bool>, - ) -> Result<()> - { - let fd = Console::current()?; - vrb!("console fd: {}", fd); - - let mut st = KbLedState::get(&fd)?; - - cap.map(|b| st.set_cap(b)); - num.map(|b| st.set_num(b)); - scr.map(|b| st.set_scr(b)); - - st.set(&fd)?; - vrb!("applied"); - - Ok(()) - } - - /** Revert the keyboard LED state. */ - fn revert_leds() -> Result<()> - { - let fd = Console::current()?; - vrb!("console fd: {}", fd); - - KbLedState::revert(&fd)?; - vrb!("reverted"); - - Ok(()) - } -} /* [impl Job] */ +} /* [impl Run for Job] */ fn main() -> Result<()> { |