use std::io::Write;
use std::time::Duration;
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
use bv_runtime::{PauseGuard, ProgressReporter};
pub struct CliProgressReporter {
bar: ProgressBar,
mp: MultiProgress,
}
impl CliProgressReporter {
fn styled(bar: ProgressBar, mp: MultiProgress) -> Self {
bar.set_style(
ProgressStyle::with_template(" {spinner:.cyan} {msg}")
.unwrap()
.tick_strings(&["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]),
);
bar.enable_steady_tick(Duration::from_millis(80));
Self { bar, mp }
}
pub fn for_multi(mp: &MultiProgress) -> Self {
Self::styled(mp.add(ProgressBar::new_spinner()), mp.clone())
}
pub fn println(&self, line: &str) {
let _ = self.mp.println(line);
}
}
impl ProgressReporter for CliProgressReporter {
fn update(&self, message: &str, _current: Option<u64>, _total: Option<u64>) {
if !message.is_empty() {
self.bar.set_message(message.to_string());
}
}
fn finish(&self, message: &str) {
self.bar.finish_and_clear();
if !message.is_empty() {
eprintln!(" {message}");
}
}
fn pause(&self) -> Box<dyn PauseGuard + '_> {
self.bar.disable_steady_tick();
self.bar.set_message(String::new());
eprint!("\r\x1b[2K");
let _ = std::io::stderr().flush();
Box::new(SpinnerPauseGuard)
}
}
struct SpinnerPauseGuard;
impl PauseGuard for SpinnerPauseGuard {}