use std::io::Write;
use ch32rv_contract::event::Event;
use ch32rv_contract::progress::ProgressSink;
use crate::args::{Cli, ProgressMode};
pub struct CliSink {
mode: ProgressMode,
}
pub fn sink(cli: &Cli) -> CliSink {
let mode = cli.progress.unwrap_or_else(|| {
if cli.json {
ProgressMode::None
} else if std::io::IsTerminal::is_terminal(&std::io::stderr()) {
ProgressMode::Bar
} else {
ProgressMode::None
}
});
CliSink { mode }
}
impl ProgressSink for CliSink {
fn event(&self, ev: &Event) {
match self.mode {
ProgressMode::None => {
if let Event::Retry {
phase,
attempt,
cause,
} = ev
{
eprintln!("retry: {phase} attempt {attempt} ({cause})");
}
}
ProgressMode::Ndjson => {
if let Ok(line) = serde_json::to_string(ev) {
let mut err = std::io::stderr().lock();
let _ = writeln!(err, "{line}");
}
}
ProgressMode::Bar => match ev {
Event::Phase { name, .. } => eprintln!("{name}..."),
Event::Retry {
phase,
attempt,
cause,
} => {
eprintln!("retry: {phase} attempt {attempt} ({cause})")
}
Event::Warn { code, msg } => eprintln!("warning[{code}]: {msg}"),
_ => {}
},
}
}
}