scanflow/
pbar.rs

1#[cfg(feature = "progress_bar")]
2use std::sync::{
3    atomic::{AtomicU64, Ordering},
4    Arc,
5};
6
7#[cfg(feature = "progress_bar")]
8use std::thread::{spawn, JoinHandle};
9
10/// Describes a progress bar.
11///
12/// This structure is active only when `progress_bar` feature is enabled.
13pub struct PBar {
14    #[cfg(feature = "progress_bar")]
15    handle: Option<JoinHandle<()>>,
16    #[cfg(feature = "progress_bar")]
17    cnt: Arc<AtomicU64>,
18}
19
20#[cfg(feature = "progress_bar")]
21impl PBar {
22    pub fn new(max_length: u64, as_bytes: bool) -> Self {
23        let cnt = Arc::new(AtomicU64::new(0));
24
25        let cnt2 = cnt.clone();
26
27        Self {
28            handle: Some(spawn(move || {
29                let mut pbar = pbr::ProgressBar::new(max_length);
30                let cnt = cnt2;
31
32                if as_bytes {
33                    pbar.set_units(pbr::Units::Bytes);
34                }
35
36                let timeout = std::time::Duration::from_millis(30);
37
38                loop {
39                    std::thread::sleep(timeout);
40                    let loaded = cnt.load(Ordering::Acquire);
41
42                    if loaded == !0 {
43                        pbar.finish();
44                        break;
45                    }
46
47                    pbar.set(loaded);
48                }
49            })),
50            cnt,
51        }
52    }
53
54    pub fn add(&self, add: u64) {
55        self.cnt.fetch_add(add, Ordering::Relaxed);
56    }
57
58    pub fn inc(&self) {
59        self.add(1);
60    }
61
62    pub fn set(&self, value: u64) {
63        self.cnt.store(value, Ordering::Relaxed);
64    }
65
66    pub fn finish(self) {}
67}
68
69#[cfg(feature = "progress_bar")]
70impl Drop for PBar {
71    fn drop(&mut self) {
72        self.cnt.store(!0, Ordering::Release);
73        self.handle.take().unwrap().join().unwrap();
74    }
75}
76
77#[cfg(not(feature = "progress_bar"))]
78impl PBar {
79    pub fn new(_max_length: u64, _as_bytes: bool) -> Self {
80        Self {}
81    }
82
83    pub fn add(&self, _add: u64) {}
84
85    pub fn inc(&self) {}
86
87    pub fn set(&self, _value: u64) {}
88
89    pub fn finish(self) {}
90}