Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/src/progress.rs @ 52300:04b9a56c2d25
rust-lib: only export very common types to the top of the crate
This was done very early in the Rust project's lifecycle and I had very little
Rust experience. Let's keep the `DirstateParents` since they'll pop up in
all higher-level code and make the rest more explicit imports to make the
imports less confusing and the lib less cluttered.
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Mon, 04 Nov 2024 11:13:05 +0100 |
parents | 92e23ba257d1 |
children | a876ab6c3fd5 |
rev | line source |
---|---|
52037
3ae7c43ad8aa
rust: add `Progress` trait for progress bars
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
1 //! Progress-bar related things |
3ae7c43ad8aa
rust: add `Progress` trait for progress bars
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
2 |
52038
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
3 use std::{ |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
4 sync::atomic::{AtomicBool, Ordering}, |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
5 time::Duration, |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
6 }; |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
7 |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
8 use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle}; |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
9 |
52037
3ae7c43ad8aa
rust: add `Progress` trait for progress bars
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
10 /// A generic determinate progress bar trait |
3ae7c43ad8aa
rust: add `Progress` trait for progress bars
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
11 pub trait Progress: Send + Sync + 'static { |
3ae7c43ad8aa
rust: add `Progress` trait for progress bars
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
12 /// Set the current position and optionally the total |
3ae7c43ad8aa
rust: add `Progress` trait for progress bars
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
13 fn update(&self, pos: u64, total: Option<u64>); |
3ae7c43ad8aa
rust: add `Progress` trait for progress bars
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
14 /// Increment the current position and optionally the total |
3ae7c43ad8aa
rust: add `Progress` trait for progress bars
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
15 fn increment(&self, step: u64, total: Option<u64>); |
3ae7c43ad8aa
rust: add `Progress` trait for progress bars
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
16 /// Declare that progress is over and the progress bar should be deleted |
3ae7c43ad8aa
rust: add `Progress` trait for progress bars
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
17 fn complete(self); |
3ae7c43ad8aa
rust: add `Progress` trait for progress bars
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
18 } |
52038
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
19 |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
20 const PROGRESS_DELAY: Duration = Duration::from_secs(1); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
21 |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
22 /// A generic (determinate) progress bar. Stays hidden until [`PROGRESS_DELAY`] |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
23 /// to prevent flickering a progress bar for super fast operations. |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
24 pub struct HgProgressBar { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
25 progress: ProgressBar, |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
26 has_been_shown: AtomicBool, |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
27 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
28 |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
29 impl HgProgressBar { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
30 // TODO pass config to check progress.disable/assume-tty/delay/etc. |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
31 /// Return a new progress bar with `topic` as the prefix. |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
32 /// The progress and total are both set to 0, and it is hidden until the |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
33 /// next call to `update` given that more than a second has elapsed. |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
34 pub fn new(topic: &str) -> Self { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
35 let template = |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
36 format!("{} {{wide_bar}} {{pos}}/{{len}} {{eta}} ", topic); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
37 let style = ProgressStyle::with_template(&template).unwrap(); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
38 let progress_bar = ProgressBar::new(0).with_style(style); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
39 // Hide the progress bar and only show it if we've elapsed more |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
40 // than a second |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
41 progress_bar.set_draw_target(ProgressDrawTarget::hidden()); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
42 Self { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
43 progress: progress_bar, |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
44 has_been_shown: false.into(), |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
45 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
46 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
47 |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
48 /// Called whenever the progress changes to determine whether to start |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
49 /// showing the progress bar |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
50 fn maybe_show(&self) { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
51 if self.progress.is_hidden() |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
52 && self.progress.elapsed() > PROGRESS_DELAY |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
53 { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
54 // Catch a race condition whereby we check if it's hidden, then |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
55 // set the draw target from another thread, then do it again from |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
56 // this thread, which results in multiple progress bar lines being |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
57 // left drawn. |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
58 let has_been_shown = |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
59 self.has_been_shown.fetch_or(true, Ordering::Relaxed); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
60 if !has_been_shown { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
61 // Here we are certain that we're the only thread that has |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
62 // set `has_been_shown` and we can change the draw target |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
63 self.progress.set_draw_target(ProgressDrawTarget::stderr()); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
64 self.progress.tick(); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
65 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
66 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
67 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
68 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
69 |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
70 impl Progress for HgProgressBar { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
71 fn update(&self, pos: u64, total: Option<u64>) { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
72 self.progress.update(|state| { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
73 state.set_pos(pos); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
74 if let Some(t) = total { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
75 state.set_len(t) |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
76 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
77 }); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
78 self.maybe_show(); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
79 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
80 |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
81 fn increment(&self, step: u64, total: Option<u64>) { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
82 self.progress.inc(step); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
83 if let Some(t) = total { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
84 self.progress.set_length(t) |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
85 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
86 self.maybe_show(); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
87 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
88 |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
89 fn complete(self) { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
90 self.progress.finish_and_clear(); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
91 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52037
diff
changeset
|
92 } |