pub mod when;
pub use when::When;
use super::super::{error::Error, log::syntax_highlight::SyntaxHighLight};
use super::Param;
use clap::{Parser, ValueHint};
use is_terminal::IsTerminal;
use std::{ffi::OsString, io::stderr};
#[derive(Parser)]
#[clap(name = "pretty-exec", rename_all = "kebab", version)]
pub struct Args {
#[clap(name = "command", value_hint = ValueHint::CommandWithArguments, trailing_var_arg = true)]
command: Vec<OsString>,
#[clap(long, name = "prompt", default_value = "$")]
prompt: String,
#[clap(long)]
skip_exec: bool,
#[clap(long, name = "color", value_enum, default_value_t = When::Auto)]
color: When,
#[clap(long)]
github_actions: bool,
}
impl Args {
pub fn syntax_highlight(&self) -> SyntaxHighLight {
ColorMode::new(
self.color,
|| self.github_actions,
|| stderr().is_terminal(),
)
.syntax_highlight()
}
pub fn param(&'_ self) -> Result<Param<'_>, Error> {
if self.command.is_empty() {
return Err(Error::ProgramNotSpecified);
}
Ok(Param {
program: self.command[0].as_os_str(),
arguments: &self.command[1..],
prompt: self.prompt.as_str(),
skip_exec: self.skip_exec,
support_github_action: self.github_actions,
syntax_highlight: self.syntax_highlight(),
})
}
}
#[must_use]
#[derive(Clone, Copy)]
#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
enum ColorMode {
Colorless,
Colorful,
}
impl ColorMode {
fn new(
color: When,
github_actions: impl FnOnce() -> bool,
is_terminal: impl FnOnce() -> bool,
) -> Self {
match color {
When::Never => return ColorMode::Colorless,
When::Always => return ColorMode::Colorful,
When::Auto => {}
}
if github_actions() || is_terminal() {
return ColorMode::Colorful;
}
ColorMode::Colorless
}
fn syntax_highlight(self) -> SyntaxHighLight {
match self {
ColorMode::Colorless => SyntaxHighLight::colorless(),
ColorMode::Colorful => SyntaxHighLight::colorful(),
}
}
}
#[cfg(test)]
mod test_color_mode {
use super::{ColorMode, When};
use itertools::Itertools;
use maplit::btreemap;
use pretty_assertions::assert_eq;
use std::collections::BTreeMap;
#[test]
fn new() {
use ColorMode::{Colorful, Colorless};
use When::{Always, Auto, Never};
let color = [Auto, Never, Always];
let github_actions = [false, true];
let is_terminal = [false, true];
let received: BTreeMap<_, _> = [color.len(), github_actions.len(), is_terminal.len()]
.into_iter()
.map(|len| 0..len)
.multi_cartesian_product()
.map(|indices| (indices[0], indices[1], indices[2]))
.map(|(i, j, k)| (color[i], github_actions[j], is_terminal[k]))
.map(|(a, b, c)| ((a, b, c), ColorMode::new(a, || b, || c)))
.collect();
dbg!(&received);
let expected = btreemap! {
(Auto, false, false) => Colorless,
(Auto, true, false) => Colorful,
(Auto, false, true) => Colorful,
(Auto, true, true) => Colorful,
(Never, false, false) => Colorless,
(Never, true, false) => Colorless,
(Never, false, true) => Colorless,
(Never, true, true) => Colorless,
(Always, false, false) => Colorful,
(Always, true, false) => Colorful,
(Always, false, true) => Colorful,
(Always, true, true) => Colorful,
};
assert_eq!(received, expected);
}
}