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