1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub struct ProgressEvent<'a> {
9 pub stage: &'a str,
10 pub step: usize,
11 pub steps: usize,
12 pub done: u64,
13 pub total: u64,
14 pub unit: &'a str,
16}
17
18pub trait ProgressSink: Send + Sync {
20 fn report(&self, event: &ProgressEvent<'_>);
21}
22
23#[derive(Debug, Clone, Copy, Default)]
25pub struct NoProgress;
26
27impl ProgressSink for NoProgress {
28 fn report(&self, _event: &ProgressEvent<'_>) {}
29}
30
31impl<F: Fn(&ProgressEvent<'_>) + Send + Sync> ProgressSink for F {
32 fn report(&self, event: &ProgressEvent<'_>) {
33 self(event)
34 }
35}
36
37#[derive(Clone, Copy)]
40pub struct Stages<'a> {
41 sink: &'a dyn ProgressSink,
42 names: &'a [(&'a str, &'a str)],
43}
44
45impl<'a> Stages<'a> {
46 pub fn new(sink: &'a dyn ProgressSink, names: &'a [(&'a str, &'a str)]) -> Self {
48 Self { sink, names }
49 }
50
51 pub fn report(&self, name: &str, done: u64, total: u64) {
53 if let Some(i) = self.names.iter().position(|(n, _)| *n == name) {
54 let (stage, unit) = self.names[i];
55 self.sink.report(&ProgressEvent { stage, step: i + 1, steps: self.names.len(), done, total, unit });
56 }
57 }
58}