Mercurial > public > mercurial-scm > hg-stable
annotate rust/hg-core/src/progress.rs @ 52769:1b7a57a5b47a
rust: add safe bindings to bdiff.c
I wrote C FFI bindings manually rather than using a bindgen build step because
there are only 2 structs and 3 functions and they're not going to change.
Note that the relative path in build.rs means that cargo publish will no longer
work. If in the future we want to publish to crates.io, we would probably need
to add a Makefile step that copies bdiff sources into the hg-core crate.
author | Mitchell Kember <mkember@janestreet.com> |
---|---|
date | Wed, 18 Dec 2024 10:35:01 -0500 |
parents | a876ab6c3fd5 |
children |
rev | line source |
---|---|
52065
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 |
52066
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
3 use std::{ |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
4 sync::atomic::{AtomicBool, Ordering}, |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
5 time::Duration, |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
6 }; |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
7 |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
8 use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle}; |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
9 |
52065
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 } |
52066
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
19 |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
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:
52065
diff
changeset
|
21 |
52342
a876ab6c3fd5
rust: fix `cargo doc` warnings
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52066
diff
changeset
|
22 /// A generic (determinate) progress bar. Stays hidden until `PROGRESS_DELAY` |
52066
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
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:
52065
diff
changeset
|
24 pub struct HgProgressBar { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
25 progress: ProgressBar, |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
26 has_been_shown: AtomicBool, |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
27 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
28 |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
29 impl HgProgressBar { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
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:
52065
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:
52065
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:
52065
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:
52065
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:
52065
diff
changeset
|
35 let template = |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
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:
52065
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:
52065
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:
52065
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:
52065
diff
changeset
|
40 // than a second |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
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:
52065
diff
changeset
|
42 Self { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
43 progress: progress_bar, |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
44 has_been_shown: false.into(), |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
45 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
46 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
47 |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
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:
52065
diff
changeset
|
49 /// showing the progress bar |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
50 fn maybe_show(&self) { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
51 if self.progress.is_hidden() |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
52 && self.progress.elapsed() > PROGRESS_DELAY |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
53 { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
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:
52065
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:
52065
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:
52065
diff
changeset
|
57 // left drawn. |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
58 let has_been_shown = |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
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:
52065
diff
changeset
|
60 if !has_been_shown { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
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:
52065
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:
52065
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:
52065
diff
changeset
|
64 self.progress.tick(); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
65 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
66 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
67 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
68 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
69 |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
70 impl Progress for HgProgressBar { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
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:
52065
diff
changeset
|
72 self.progress.update(|state| { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
73 state.set_pos(pos); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
74 if let Some(t) = total { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
75 state.set_len(t) |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
76 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
77 }); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
78 self.maybe_show(); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
79 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
80 |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
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:
52065
diff
changeset
|
82 self.progress.inc(step); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
83 if let Some(t) = total { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
84 self.progress.set_length(t) |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
85 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
86 self.maybe_show(); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
87 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
88 |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
89 fn complete(self) { |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
90 self.progress.finish_and_clear(); |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
91 } |
92e23ba257d1
rust-hg-cpython: add an `HgProgressBar` util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52065
diff
changeset
|
92 } |