1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use std::cmp::min;
use std::sync::{Arc, Mutex};
use crate::pipe::{prelude::*, PipeReader, PipeWriter};
pub struct ProgressPipe {
cur: u64,
len: u64,
reporter: Option<Arc<Mutex<ProgressReporter>>>,
}
impl ProgressPipe {
pub fn new(cur: u64, len: u64, reporter: Option<Arc<Mutex<ProgressReporter>>>) -> Self {
Self { cur, len, reporter }
}
pub fn zero(len: u64, reporter: Option<Arc<Mutex<ProgressReporter>>>) -> Self {
Self::new(0, len, reporter)
}
}
impl Pipe for ProgressPipe {
type Reader = ProgressReader;
type Writer = ProgressWriter;
fn pipe(&mut self, input: &[u8]) -> (usize, Option<Vec<u8>>) {
let (len, data) = self.pipe_transparent(input);
self.cur = min(self.cur + len as u64, self.len);
if let Some(reporter) = self.reporter.as_mut() {
let progress = self.cur;
let _ = reporter.lock().map(|mut r| r.progress(progress));
}
(len, data)
}
}
pub type ProgressReader = PipeReader<ProgressPipe>;
pub type ProgressWriter = PipeWriter<ProgressPipe>;
impl PipeLen for ProgressReader {
fn len_in(&self) -> usize {
self.pipe.len as usize
}
fn len_out(&self) -> usize {
self.pipe.len as usize
}
}
impl PipeLen for ProgressWriter {
fn len_in(&self) -> usize {
self.pipe.len as usize
}
fn len_out(&self) -> usize {
self.pipe.len as usize
}
}
pub trait ProgressReporter: Send {
fn start(&mut self, total: u64);
fn progress(&mut self, progress: u64);
fn finish(&mut self);
}