use std::fmt;
use std::io::IsTerminal;
use std::io::Write;
pub struct Hint {
quiet: bool,
first: bool,
}
impl Hint {
pub fn new(quiet: bool) -> Self {
Hint {
quiet,
first: true,
}
}
pub fn hint(mut self, msg: fmt::Arguments) -> Self {
if ! self.quiet {
weprintln!();
weprintln!(
initial_indent=if self.first { "Hint: " } else { " " },
subsequent_indent=" ",
"{}", msg);
self.first = false;
}
self
}
pub fn sq(self) -> Command {
Command::new(self, "sq")
}
pub fn command(self, argv0: &str) -> Command {
Command::new(self, argv0)
}
}
pub struct Command {
hint: Hint,
args: Vec<(String, Option<String>)>,
}
impl Command {
fn new(hint: Hint, argv0: &str) -> Self {
Command {
hint,
args: vec![(argv0.into(), None)],
}
}
pub fn arg<S: ToString>(mut self, arg: S) -> Self {
self.args.push((arg.to_string(), None));
self
}
pub fn arg_hidden<S: ToString, R: ToString>(
mut self, arg: S, replacement: R)
-> Self
{
self.args.push((arg.to_string(), Some(replacement.to_string())));
self
}
pub fn arg_value<S: ToString, V: ToString>(mut self, arg: S, value: V)
-> Self
{
self.args.push(
(format!("{}={}", arg.to_string(), value.to_string()),
None));
self
}
pub fn arg_value_hidden<S: ToString, V: ToString, R: ToString>(
mut self, arg: S, value: V, replacement_value: R)
-> Self
{
self.args.push(
(format!("{}={}", arg.to_string(), value.to_string()),
Some(format!("{}={}",
arg.to_string(),
replacement_value.to_string()))));
self
}
pub fn done(self) -> Hint {
if ! self.hint.quiet {
let mut stdout = std::io::stdout();
if stdout.is_terminal() {
let _ = stdout.flush();
}
let width = crate::output::wrapping::stderr_terminal_width();
let args = self.args.iter()
.map(|(arg, replacement)| {
if let Some(replacement) = replacement {
replacement
} else {
arg
}
})
.collect::<Vec<_>>();
eprintln!();
eprintln!("{}", crate::cli::examples::wrap_command(
&args, &[], " ", width, " ", width));
}
if cfg!(debug_assertions) && self.args[0].0 == "sq" {
let cli = crate::cli::build(false);
if let Err(e)
= cli.try_get_matches_from(self.args.iter().map(|(a, _)| a))
{
panic!("bad hint, parsing {}", e);
}
}
self.hint
}
}