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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }