#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ProgressEvent<'a> {
pub stage: &'a str,
pub step: usize,
pub steps: usize,
pub done: u64,
pub total: u64,
pub unit: &'a str,
}
pub trait ProgressSink: Send + Sync {
fn report(&self, event: &ProgressEvent<'_>);
}
#[derive(Debug, Clone, Copy, Default)]
pub struct NoProgress;
impl ProgressSink for NoProgress {
fn report(&self, _event: &ProgressEvent<'_>) {}
}
impl<F: Fn(&ProgressEvent<'_>) + Send + Sync> ProgressSink for F {
fn report(&self, event: &ProgressEvent<'_>) {
self(event)
}
}
#[derive(Clone, Copy)]
pub struct Stages<'a> {
sink: &'a dyn ProgressSink,
names: &'a [(&'a str, &'a str)],
}
impl<'a> Stages<'a> {
pub fn new(sink: &'a dyn ProgressSink, names: &'a [(&'a str, &'a str)]) -> Self {
Self { sink, names }
}
pub fn report(&self, name: &str, done: u64, total: u64) {
if let Some(i) = self.names.iter().position(|(n, _)| *n == name) {
let (stage, unit) = self.names[i];
self.sink.report(&ProgressEvent { stage, step: i + 1, steps: self.names.len(), done, total, unit });
}
}
}