summaryrefslogtreecommitdiffstats
path: root/vendor/indicatif/examples
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
commitc23a457e72abe608715ac76f076f47dc42af07a5 (patch)
tree2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /vendor/indicatif/examples
parentReleasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz
rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/indicatif/examples')
-rw-r--r--vendor/indicatif/examples/cargo.rs122
-rw-r--r--vendor/indicatif/examples/cargowrap.rs41
-rw-r--r--vendor/indicatif/examples/download-continued.rs29
-rw-r--r--vendor/indicatif/examples/download-speed.rs24
-rw-r--r--vendor/indicatif/examples/download.rs25
-rw-r--r--vendor/indicatif/examples/fastbar.rs23
-rw-r--r--vendor/indicatif/examples/finebars.rs43
-rw-r--r--vendor/indicatif/examples/iterator.rs31
-rw-r--r--vendor/indicatif/examples/log.rs14
-rw-r--r--vendor/indicatif/examples/long-spinner.rs27
-rw-r--r--vendor/indicatif/examples/message.rs11
-rw-r--r--vendor/indicatif/examples/morebars.rs28
-rw-r--r--vendor/indicatif/examples/multi-tree-ext.rs280
-rw-r--r--vendor/indicatif/examples/multi-tree.rs189
-rw-r--r--vendor/indicatif/examples/multi.rs67
-rw-r--r--vendor/indicatif/examples/single.rs13
-rw-r--r--vendor/indicatif/examples/slow.rs12
-rw-r--r--vendor/indicatif/examples/spinner-loop.rs18
-rw-r--r--vendor/indicatif/examples/steady.rs50
-rw-r--r--vendor/indicatif/examples/tokio.rs34
-rw-r--r--vendor/indicatif/examples/yarnish.rs97
21 files changed, 1178 insertions, 0 deletions
diff --git a/vendor/indicatif/examples/cargo.rs b/vendor/indicatif/examples/cargo.rs
new file mode 100644
index 000000000..02b18b21b
--- /dev/null
+++ b/vendor/indicatif/examples/cargo.rs
@@ -0,0 +1,122 @@
+use std::sync::{mpsc, Arc, Mutex};
+use std::thread;
+use std::time::{Duration, Instant};
+
+use console::{Style, Term};
+use indicatif::{HumanDuration, ProgressBar, ProgressStyle};
+use rand::Rng;
+
+static CRATES: &[(&str, &str)] = &[
+ ("console", "v0.14.1"),
+ ("lazy_static", "v1.4.0"),
+ ("libc", "v0.2.93"),
+ ("regex", "v1.4.6"),
+ ("regex-syntax", "v0.6.23"),
+ ("terminal_size", "v0.1.16"),
+ ("libc", "v0.2.93"),
+ ("unicode-width", "v0.1.8"),
+ ("lazy_static", "v1.4.0"),
+ ("number_prefix", "v0.4.0"),
+ ("regex", "v1.4.6"),
+ ("rand", "v0.8.3"),
+ ("getrandom", "v0.2.2"),
+ ("cfg-if", "v1.0.0"),
+ ("libc", "v0.2.93"),
+ ("rand_chacha", "v0.3.0"),
+ ("ppv-lite86", "v0.2.10"),
+ ("rand_core", "v0.6.2"),
+ ("getrandom", "v0.2.2"),
+ ("rand_core", "v0.6.2"),
+ ("tokio", "v1.5.0"),
+ ("bytes", "v1.0.1"),
+ ("pin-project-lite", "v0.2.6"),
+ ("slab", "v0.4.3"),
+ ("indicatif", "v0.15.0"),
+];
+
+fn main() {
+ // number of cpus
+ const NUM_CPUS: usize = 4;
+ let start = Instant::now();
+
+ // mimic cargo progress bar although it behaves a bit different
+ let pb = ProgressBar::new(CRATES.len() as u64);
+ pb.set_style(
+ ProgressStyle::with_template(
+ // note that bar size is fixed unlike cargo which is dynamic
+ // and also the truncation in cargo uses trailers (`...`)
+ if Term::stdout().size().1 > 80 {
+ "{prefix:>12.cyan.bold} [{bar:57}] {pos}/{len} {wide_msg}"
+ } else {
+ "{prefix:>12.cyan.bold} [{bar:57}] {pos}/{len}"
+ },
+ )
+ .unwrap()
+ .progress_chars("=> "),
+ );
+ pb.set_prefix("Building");
+
+ // process in another thread
+ // crates to be iterated but not exactly a tree
+ let crates = Arc::new(Mutex::new(CRATES.iter()));
+ let (tx, rx) = mpsc::channel();
+ for n in 0..NUM_CPUS {
+ let tx = tx.clone();
+ let crates = crates.clone();
+ thread::spawn(move || {
+ let mut rng = rand::thread_rng();
+ loop {
+ let krate = crates.lock().unwrap().next();
+ // notify main thread if n thread is processing a crate
+ tx.send((n, krate)).unwrap();
+ if let Some(krate) = krate {
+ thread::sleep(Duration::from_millis(
+ // last compile and linking is always slow, let's mimic that
+ if CRATES.last() == Some(krate) {
+ rng.gen_range(1_000..2_000)
+ } else {
+ rng.gen_range(250..1_000)
+ },
+ ));
+ } else {
+ break;
+ }
+ }
+ });
+ }
+ // drop tx to stop waiting
+ drop(tx);
+
+ let green_bold = Style::new().green().bold();
+
+ // do progress drawing in main thread
+ let mut processing = vec![None; NUM_CPUS];
+ while let Ok((n, krate)) = rx.recv() {
+ processing[n] = krate;
+ let crates: Vec<&str> = processing
+ .iter()
+ .filter_map(|t| t.copied().map(|(name, _)| name))
+ .collect();
+ pb.set_message(crates.join(", "));
+ if let Some((name, version)) = krate {
+ // crate is being built
+ let line = format!(
+ "{:>12} {} {}",
+ green_bold.apply_to("Compiling"),
+ name,
+ version
+ );
+ pb.println(line);
+
+ pb.inc(1);
+ }
+ }
+ pb.finish_and_clear();
+
+ // compilation is finished
+ println!(
+ "{:>12} dev [unoptimized + debuginfo] target(s) in {}",
+ green_bold.apply_to("Finished"),
+ HumanDuration(start.elapsed())
+ );
+}
diff --git a/vendor/indicatif/examples/cargowrap.rs b/vendor/indicatif/examples/cargowrap.rs
new file mode 100644
index 000000000..354b6e0f6
--- /dev/null
+++ b/vendor/indicatif/examples/cargowrap.rs
@@ -0,0 +1,41 @@
+use std::io::{BufRead, BufReader};
+use std::process;
+use std::time::{Duration, Instant};
+
+use indicatif::{HumanDuration, ProgressBar, ProgressStyle};
+
+pub fn main() {
+ let started = Instant::now();
+
+ println!("Compiling package in release mode...");
+
+ let pb = ProgressBar::new_spinner();
+ pb.enable_steady_tick(Duration::from_millis(200));
+ pb.set_style(
+ ProgressStyle::with_template("{spinner:.dim.bold} cargo: {wide_msg}")
+ .unwrap()
+ .tick_chars("/|\\- "),
+ );
+
+ let mut p = process::Command::new("cargo")
+ .arg("build")
+ .arg("--release")
+ .stderr(process::Stdio::piped())
+ .spawn()
+ .unwrap();
+
+ for line in BufReader::new(p.stderr.take().unwrap()).lines() {
+ let line = line.unwrap();
+ let stripped_line = line.trim();
+ if !stripped_line.is_empty() {
+ pb.set_message(stripped_line.to_owned());
+ }
+ pb.tick();
+ }
+
+ p.wait().unwrap();
+
+ pb.finish_and_clear();
+
+ println!("Done in {}", HumanDuration(started.elapsed()));
+}
diff --git a/vendor/indicatif/examples/download-continued.rs b/vendor/indicatif/examples/download-continued.rs
new file mode 100644
index 000000000..c9a76b6cf
--- /dev/null
+++ b/vendor/indicatif/examples/download-continued.rs
@@ -0,0 +1,29 @@
+use std::cmp::min;
+use std::thread;
+use std::time::Duration;
+
+use indicatif::{ProgressBar, ProgressStyle};
+
+fn main() {
+ let mut downloaded = 69369369;
+ let total_size = 231231231;
+
+ let pb = ProgressBar::new(total_size);
+ pb.set_style(
+ ProgressStyle::with_template(
+ "{spinner:.green} [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})",
+ )
+ .unwrap()
+ .progress_chars("#>-"),
+ );
+ pb.set_position(downloaded);
+ pb.reset_eta();
+
+ while downloaded < total_size {
+ downloaded = min(downloaded + 123211, total_size);
+ pb.set_position(downloaded);
+ thread::sleep(Duration::from_millis(12));
+ }
+
+ pb.finish_with_message("downloaded");
+}
diff --git a/vendor/indicatif/examples/download-speed.rs b/vendor/indicatif/examples/download-speed.rs
new file mode 100644
index 000000000..da5a80fa3
--- /dev/null
+++ b/vendor/indicatif/examples/download-speed.rs
@@ -0,0 +1,24 @@
+use std::cmp::min;
+use std::thread;
+use std::time::Duration;
+
+use indicatif::{ProgressBar, ProgressStyle};
+
+fn main() {
+ let mut downloaded = 0;
+ let total_size = 231231231;
+
+ let pb = ProgressBar::new(total_size);
+ pb.set_style(ProgressStyle::with_template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({bytes_per_sec}, {eta})")
+ .unwrap()
+ .progress_chars("#>-"));
+
+ while downloaded < total_size {
+ let new = min(downloaded + 223211, total_size);
+ downloaded = new;
+ pb.set_position(new);
+ thread::sleep(Duration::from_millis(12));
+ }
+
+ pb.finish_with_message("downloaded");
+}
diff --git a/vendor/indicatif/examples/download.rs b/vendor/indicatif/examples/download.rs
new file mode 100644
index 000000000..c3f92027a
--- /dev/null
+++ b/vendor/indicatif/examples/download.rs
@@ -0,0 +1,25 @@
+use std::thread;
+use std::time::Duration;
+use std::{cmp::min, fmt::Write};
+
+use indicatif::{ProgressBar, ProgressState, ProgressStyle};
+
+fn main() {
+ let mut downloaded = 0;
+ let total_size = 231231231;
+
+ let pb = ProgressBar::new(total_size);
+ pb.set_style(ProgressStyle::with_template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})")
+ .unwrap()
+ .with_key("eta", |state: &ProgressState, w: &mut dyn Write| write!(w, "{:.1}s", state.eta().as_secs_f64()).unwrap())
+ .progress_chars("#>-"));
+
+ while downloaded < total_size {
+ let new = min(downloaded + 223211, total_size);
+ downloaded = new;
+ pb.set_position(new);
+ thread::sleep(Duration::from_millis(12));
+ }
+
+ pb.finish_with_message("downloaded");
+}
diff --git a/vendor/indicatif/examples/fastbar.rs b/vendor/indicatif/examples/fastbar.rs
new file mode 100644
index 000000000..1b71f0ca3
--- /dev/null
+++ b/vendor/indicatif/examples/fastbar.rs
@@ -0,0 +1,23 @@
+use indicatif::ProgressBar;
+
+fn many_units_of_easy_work(n: u64, label: &str) {
+ let pb = ProgressBar::new(n);
+
+ let mut sum = 0;
+ for i in 0..n {
+ // Any quick computation, followed by an update to the progress bar.
+ sum += 2 * i + 3;
+ pb.inc(1);
+ }
+ pb.finish();
+
+ println!("[{}] Sum ({}) calculated in {:?}", label, sum, pb.elapsed());
+}
+
+fn main() {
+ const N: u64 = 1 << 20;
+
+ // Perform a long sequence of many simple computations monitored by a
+ // default progress bar.
+ many_units_of_easy_work(N, "Default progress bar ");
+}
diff --git a/vendor/indicatif/examples/finebars.rs b/vendor/indicatif/examples/finebars.rs
new file mode 100644
index 000000000..dffb967b1
--- /dev/null
+++ b/vendor/indicatif/examples/finebars.rs
@@ -0,0 +1,43 @@
+use std::thread;
+use std::time::Duration;
+
+use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
+use rand::{thread_rng, Rng};
+
+fn main() {
+ let styles = [
+ ("Rough bar:", "█ ", "red"),
+ ("Fine bar: ", "█▉▊▋▌▍▎▏ ", "yellow"),
+ ("Vertical: ", "█▇▆▅▄▃▂▁ ", "green"),
+ ("Fade in: ", "█▓▒░ ", "blue"),
+ ("Blocky: ", "█▛▌▖ ", "magenta"),
+ ];
+
+ let m = MultiProgress::new();
+
+ let handles: Vec<_> = styles
+ .iter()
+ .map(|s| {
+ let pb = m.add(ProgressBar::new(512));
+ pb.set_style(
+ ProgressStyle::with_template(&format!("{{prefix:.bold}}▕{{bar:.{}}}▏{{msg}}", s.2))
+ .unwrap()
+ .progress_chars(s.1),
+ );
+ pb.set_prefix(s.0);
+ let wait = Duration::from_millis(thread_rng().gen_range(10..30));
+ thread::spawn(move || {
+ for i in 0..512 {
+ thread::sleep(wait);
+ pb.inc(1);
+ pb.set_message(format!("{:3}%", 100 * i / 512));
+ }
+ pb.finish_with_message("100%");
+ })
+ })
+ .collect();
+
+ for h in handles {
+ let _ = h.join();
+ }
+}
diff --git a/vendor/indicatif/examples/iterator.rs b/vendor/indicatif/examples/iterator.rs
new file mode 100644
index 000000000..8f4004720
--- /dev/null
+++ b/vendor/indicatif/examples/iterator.rs
@@ -0,0 +1,31 @@
+use std::thread;
+use std::time::Duration;
+
+use indicatif::{ProgressBar, ProgressIterator, ProgressStyle};
+
+fn main() {
+ // Default styling, attempt to use Iterator::size_hint to count input size
+ for _ in (0..1000).progress() {
+ // ...
+ thread::sleep(Duration::from_millis(5));
+ }
+
+ // Provide explicit number of elements in iterator
+ for _ in (0..1000).progress_count(1000) {
+ // ...
+ thread::sleep(Duration::from_millis(5));
+ }
+
+ // Provide a custom bar style
+ let pb = ProgressBar::new(1000);
+ pb.set_style(
+ ProgressStyle::with_template(
+ "{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] ({pos}/{len}, ETA {eta})",
+ )
+ .unwrap(),
+ );
+ for _ in (0..1000).progress_with(pb) {
+ // ...
+ thread::sleep(Duration::from_millis(5));
+ }
+}
diff --git a/vendor/indicatif/examples/log.rs b/vendor/indicatif/examples/log.rs
new file mode 100644
index 000000000..26d506cd0
--- /dev/null
+++ b/vendor/indicatif/examples/log.rs
@@ -0,0 +1,14 @@
+use std::thread;
+use std::time::Duration;
+
+use indicatif::ProgressBar;
+
+fn main() {
+ let pb = ProgressBar::new(100);
+ for i in 0..100 {
+ thread::sleep(Duration::from_millis(25));
+ pb.println(format!("[+] finished #{i}"));
+ pb.inc(1);
+ }
+ pb.finish_with_message("done");
+}
diff --git a/vendor/indicatif/examples/long-spinner.rs b/vendor/indicatif/examples/long-spinner.rs
new file mode 100644
index 000000000..6b145487b
--- /dev/null
+++ b/vendor/indicatif/examples/long-spinner.rs
@@ -0,0 +1,27 @@
+use std::thread;
+use std::time::Duration;
+
+use indicatif::{ProgressBar, ProgressStyle};
+
+fn main() {
+ let pb = ProgressBar::new_spinner();
+ pb.enable_steady_tick(Duration::from_millis(120));
+ pb.set_style(
+ ProgressStyle::with_template("{spinner:.blue} {msg}")
+ .unwrap()
+ // For more spinners check out the cli-spinners project:
+ // https://github.com/sindresorhus/cli-spinners/blob/master/spinners.json
+ .tick_strings(&[
+ "▹▹▹▹▹",
+ "▸▹▹▹▹",
+ "▹▸▹▹▹",
+ "▹▹▸▹▹",
+ "▹▹▹▸▹",
+ "▹▹▹▹▸",
+ "▪▪▪▪▪",
+ ]),
+ );
+ pb.set_message("Calculating...");
+ thread::sleep(Duration::from_secs(5));
+ pb.finish_with_message("Done");
+}
diff --git a/vendor/indicatif/examples/message.rs b/vendor/indicatif/examples/message.rs
new file mode 100644
index 000000000..d15781ae9
--- /dev/null
+++ b/vendor/indicatif/examples/message.rs
@@ -0,0 +1,11 @@
+use std::{thread, time::Duration};
+
+use indicatif::ProgressBar;
+
+fn main() {
+ let pb = ProgressBar::new(100).with_message("Frobbing the widget");
+ for _ in 0..100 {
+ thread::sleep(Duration::from_millis(30));
+ pb.inc(1);
+ }
+}
diff --git a/vendor/indicatif/examples/morebars.rs b/vendor/indicatif/examples/morebars.rs
new file mode 100644
index 000000000..30b664f00
--- /dev/null
+++ b/vendor/indicatif/examples/morebars.rs
@@ -0,0 +1,28 @@
+use std::sync::Arc;
+use std::thread;
+use std::time::Duration;
+
+use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
+
+fn main() {
+ let m = Arc::new(MultiProgress::new());
+ let sty = ProgressStyle::with_template("{bar:40.green/yellow} {pos:>7}/{len:7}").unwrap();
+
+ let pb = m.add(ProgressBar::new(5));
+ pb.set_style(sty.clone());
+
+ // make sure we show up at all. otherwise no rendering
+ // event.
+ pb.tick();
+ for _ in 0..5 {
+ let pb2 = m.add(ProgressBar::new(128));
+ pb2.set_style(sty.clone());
+ for _ in 0..128 {
+ thread::sleep(Duration::from_millis(5));
+ pb2.inc(1);
+ }
+ pb2.finish();
+ pb.inc(1);
+ }
+ pb.finish_with_message("done");
+}
diff --git a/vendor/indicatif/examples/multi-tree-ext.rs b/vendor/indicatif/examples/multi-tree-ext.rs
new file mode 100644
index 000000000..065154899
--- /dev/null
+++ b/vendor/indicatif/examples/multi-tree-ext.rs
@@ -0,0 +1,280 @@
+use clap::Parser;
+use std::fmt::Debug;
+use std::sync::atomic::{AtomicUsize, Ordering};
+use std::sync::Arc;
+use std::thread;
+use std::time::Duration;
+
+use console::style;
+use indicatif::{MultiProgress, MultiProgressAlignment, ProgressBar, ProgressStyle};
+use once_cell::sync::Lazy;
+use rand::rngs::ThreadRng;
+use rand::{Rng, RngCore};
+
+#[derive(Debug, Clone)]
+enum Action {
+ ModifyTree(usize),
+ IncProgressBar(usize),
+ Stop,
+}
+
+#[derive(Clone, Debug)]
+enum Elem {
+ AddItem(Item),
+ RemoveItem(Index),
+}
+
+#[derive(Clone, Debug)]
+struct Item {
+ key: String,
+ index: usize,
+ indent: usize,
+ progress_bar: ProgressBar,
+}
+
+#[derive(Clone, Debug)]
+struct Index(usize);
+
+const PB_LEN: u64 = 32;
+static ELEM_IDX: AtomicUsize = AtomicUsize::new(0);
+
+static ELEMENTS: Lazy<[Elem; 27]> = Lazy::new(|| {
+ [
+ Elem::AddItem(Item {
+ indent: 9,
+ index: 0,
+ progress_bar: ProgressBar::new(PB_LEN),
+ key: "dog".to_string(),
+ }),
+ Elem::AddItem(Item {
+ indent: 0,
+ index: 0,
+ progress_bar: ProgressBar::new(PB_LEN),
+ key: "temp_1".to_string(),
+ }),
+ Elem::AddItem(Item {
+ indent: 8,
+ index: 1,
+ progress_bar: ProgressBar::new(PB_LEN),
+ key: "lazy".to_string(),
+ }),
+ Elem::AddItem(Item {
+ indent: 0,
+ index: 1,
+ progress_bar: ProgressBar::new(PB_LEN),
+ key: "temp_2".to_string(),
+ }),
+ Elem::AddItem(Item {
+ indent: 1,
+ index: 0,
+ progress_bar: ProgressBar::new(PB_LEN),
+ key: "the".to_string(),
+ }),
+ Elem::AddItem(Item {
+ indent: 0,
+ index: 0,
+ progress_bar: ProgressBar::new(PB_LEN),
+ key: "temp_3".to_string(),
+ }),
+ Elem::AddItem(Item {
+ indent: 7,
+ index: 3,
+ progress_bar: ProgressBar::new(PB_LEN),
+ key: "a".to_string(),
+ }),
+ Elem::AddItem(Item {
+ indent: 0,
+ index: 3,
+ progress_bar: ProgressBar::new(PB_LEN),
+ key: "temp_4".to_string(),
+ }),
+ Elem::AddItem(Item {
+ indent: 6,
+ index: 2,
+ progress_bar: ProgressBar::new(PB_LEN),
+ key: "over".to_string(),
+ }),
+ Elem::RemoveItem(Index(6)),
+ Elem::RemoveItem(Index(4)),
+ Elem::RemoveItem(Index(3)),
+ Elem::RemoveItem(Index(0)),
+ Elem::AddItem(Item {
+ indent: 0,
+ index: 2,
+ progress_bar: ProgressBar::new(PB_LEN),
+ key: "temp_5".to_string(),
+ }),
+ Elem::AddItem(Item {
+ indent: 4,
+ index: 1,
+ progress_bar: ProgressBar::new(PB_LEN),
+ key: "fox".to_string(),
+ }),
+ Elem::AddItem(Item {
+ indent: 0,
+ index: 1,
+ progress_bar: ProgressBar::new(PB_LEN),
+ key: "temp_6".to_string(),
+ }),
+ Elem::AddItem(Item {
+ indent: 2,
+ index: 1,
+ progress_bar: ProgressBar::new(PB_LEN),
+ key: "quick".to_string(),
+ }),
+ Elem::AddItem(Item {
+ indent: 0,
+ index: 1,
+ progress_bar: ProgressBar::new(PB_LEN),
+ key: "temp_7".to_string(),
+ }),
+ Elem::AddItem(Item {
+ indent: 5,
+ index: 5,
+ progress_bar: ProgressBar::new(PB_LEN),
+ key: "jumps".to_string(),
+ }),
+ Elem::AddItem(Item {
+ indent: 0,
+ index: 5,
+ progress_bar: ProgressBar::new(PB_LEN),
+ key: "temp_8".to_string(),
+ }),
+ Elem::AddItem(Item {
+ indent: 3,
+ index: 4,
+ progress_bar: ProgressBar::new(PB_LEN),
+ key: "brown".to_string(),
+ }),
+ Elem::AddItem(Item {
+ indent: 0,
+ index: 3,
+ progress_bar: ProgressBar::new(PB_LEN),
+ key: "temp_9".to_string(),
+ }),
+ Elem::RemoveItem(Index(10)),
+ Elem::RemoveItem(Index(7)),
+ Elem::RemoveItem(Index(4)),
+ Elem::RemoveItem(Index(3)),
+ Elem::RemoveItem(Index(1)),
+ ]
+});
+
+#[derive(Debug, Parser)]
+pub struct Config {
+ #[clap(long)]
+ bottom_alignment: bool,
+}
+
+/// The example demonstrates the usage of `MultiProgress` and further extends `multi-tree` example.
+/// Now the example has 3 different actions implemented, and the item tree can be modified
+/// by inserting or removing progress bars. The progress bars to be removed eventually
+/// have messages with pattern `"temp_*"`.
+///
+/// Also the command option `--bottom-alignment` is used to control the vertical alignment of the
+/// `MultiProgress`. To enable this run it with
+/// ```ignore
+/// cargo run --example multi-tree-ext -- --bottom-alignment
+/// ```
+pub fn main() {
+ let conf: Config = Config::parse();
+ let mp = Arc::new(MultiProgress::new());
+ let alignment = if conf.bottom_alignment {
+ MultiProgressAlignment::Bottom
+ } else {
+ MultiProgressAlignment::Top
+ };
+ mp.set_alignment(alignment);
+ let sty_main = ProgressStyle::with_template("{bar:40.green/yellow} {pos:>4}/{len:4}").unwrap();
+ let sty_aux =
+ ProgressStyle::with_template("[{pos:>2}/{len:2}] {prefix}{spinner:.green} {msg}").unwrap();
+ let sty_fin = ProgressStyle::with_template("[{pos:>2}/{len:2}] {prefix}{msg}").unwrap();
+
+ let pb_main = mp.add(ProgressBar::new(
+ ELEMENTS
+ .iter()
+ .map(|e| match e {
+ Elem::AddItem(item) => item.progress_bar.length().unwrap(),
+ Elem::RemoveItem(_) => 1,
+ })
+ .sum(),
+ ));
+
+ pb_main.set_style(sty_main);
+ for e in ELEMENTS.iter() {
+ match e {
+ Elem::AddItem(item) => item.progress_bar.set_style(sty_aux.clone()),
+ Elem::RemoveItem(_) => {}
+ }
+ }
+
+ let mut items: Vec<&Item> = Vec::with_capacity(ELEMENTS.len());
+
+ let mp2 = Arc::clone(&mp);
+ let mut rng = ThreadRng::default();
+ pb_main.tick();
+ loop {
+ match get_action(&mut rng, &items) {
+ Action::Stop => {
+ // all elements were exhausted
+ pb_main.finish();
+ return;
+ }
+ Action::ModifyTree(elem_idx) => match &ELEMENTS[elem_idx] {
+ Elem::AddItem(item) => {
+ let pb = mp2.insert(item.index, item.progress_bar.clone());
+ pb.set_prefix(" ".repeat(item.indent));
+ pb.set_message(&item.key);
+ items.insert(item.index, item);
+ }
+ Elem::RemoveItem(Index(index)) => {
+ let item = items.remove(*index);
+ let pb = &item.progress_bar;
+ mp2.remove(pb);
+ pb_main.inc(pb.length().unwrap() - pb.position());
+ }
+ },
+ Action::IncProgressBar(item_idx) => {
+ let item = &items[item_idx];
+ item.progress_bar.inc(1);
+ let pos = item.progress_bar.position();
+ if pos >= item.progress_bar.length().unwrap() {
+ item.progress_bar.set_style(sty_fin.clone());
+ item.progress_bar.finish_with_message(format!(
+ "{} {}",
+ style("✔").green(),
+ item.key
+ ));
+ }
+ pb_main.inc(1);
+ }
+ }
+ thread::sleep(Duration::from_millis(20));
+ }
+}
+
+/// The function guarantees to return the action, that is valid for the current tree.
+fn get_action(rng: &mut dyn RngCore, items: &[&Item]) -> Action {
+ let elem_idx = ELEM_IDX.load(Ordering::SeqCst);
+ // the indices of those items, that not completed yet
+ let uncompleted = items
+ .iter()
+ .enumerate()
+ .filter(|(_, item)| {
+ let pos = item.progress_bar.position();
+ pos < item.progress_bar.length().unwrap()
+ })
+ .map(|(idx, _)| idx)
+ .collect::<Vec<usize>>();
+ let k = rng.gen_range(0..16);
+ if (k > 0 || k == 0 && elem_idx == ELEMENTS.len()) && !uncompleted.is_empty() {
+ let idx = rng.gen_range(0..uncompleted.len() as u64) as usize;
+ Action::IncProgressBar(uncompleted[idx])
+ } else if elem_idx < ELEMENTS.len() {
+ ELEM_IDX.fetch_add(1, Ordering::SeqCst);
+ Action::ModifyTree(elem_idx)
+ } else {
+ // nothing to do more
+ Action::Stop
+ }
+}
diff --git a/vendor/indicatif/examples/multi-tree.rs b/vendor/indicatif/examples/multi-tree.rs
new file mode 100644
index 000000000..3435424ad
--- /dev/null
+++ b/vendor/indicatif/examples/multi-tree.rs
@@ -0,0 +1,189 @@
+use std::fmt::Debug;
+use std::sync::{Arc, Mutex};
+use std::thread;
+use std::time::Duration;
+
+use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
+use once_cell::sync::Lazy;
+use rand::rngs::ThreadRng;
+use rand::{Rng, RngCore};
+
+#[derive(Debug, Clone)]
+enum Action {
+ AddProgressBar(usize),
+ IncProgressBar(usize),
+}
+
+#[derive(Clone, Debug)]
+struct Elem {
+ key: String,
+ index: usize,
+ indent: usize,
+ progress_bar: ProgressBar,
+}
+
+static ELEMENTS: Lazy<[Elem; 9]> = Lazy::new(|| {
+ [
+ Elem {
+ indent: 1,
+ index: 0,
+ progress_bar: ProgressBar::new(32),
+ key: "jumps".to_string(),
+ },
+ Elem {
+ indent: 2,
+ index: 1,
+ progress_bar: ProgressBar::new(32),
+ key: "lazy".to_string(),
+ },
+ Elem {
+ indent: 0,
+ index: 0,
+ progress_bar: ProgressBar::new(32),
+ key: "the".to_string(),
+ },
+ Elem {
+ indent: 3,
+ index: 3,
+ progress_bar: ProgressBar::new(32),
+ key: "dog".to_string(),
+ },
+ Elem {
+ indent: 2,
+ index: 2,
+ progress_bar: ProgressBar::new(32),
+ key: "over".to_string(),
+ },
+ Elem {
+ indent: 2,
+ index: 1,
+ progress_bar: ProgressBar::new(32),
+ key: "brown".to_string(),
+ },
+ Elem {
+ indent: 1,
+ index: 1,
+ progress_bar: ProgressBar::new(32),
+ key: "quick".to_string(),
+ },
+ Elem {
+ indent: 3,
+ index: 5,
+ progress_bar: ProgressBar::new(32),
+ key: "a".to_string(),
+ },
+ Elem {
+ indent: 3,
+ index: 3,
+ progress_bar: ProgressBar::new(32),
+ key: "fox".to_string(),
+ },
+ ]
+});
+
+/// The example implements the tree-like collection of progress bars, where elements are
+/// added on the fly and progress bars get incremented until all elements is added and
+/// all progress bars finished.
+/// On each iteration `get_action` function returns some action, and when the tree gets
+/// complete, the function returns `None`, which finishes the loop.
+fn main() {
+ let mp = Arc::new(MultiProgress::new());
+ let sty_main = ProgressStyle::with_template("{bar:40.green/yellow} {pos:>4}/{len:4}").unwrap();
+ let sty_aux = ProgressStyle::with_template("{spinner:.green} {msg} {pos:>4}/{len:4}").unwrap();
+
+ let pb_main = mp.add(ProgressBar::new(
+ ELEMENTS
+ .iter()
+ .map(|e| e.progress_bar.length().unwrap())
+ .sum(),
+ ));
+ pb_main.set_style(sty_main);
+ for elem in ELEMENTS.iter() {
+ elem.progress_bar.set_style(sty_aux.clone());
+ }
+
+ let tree: Arc<Mutex<Vec<&Elem>>> = Arc::new(Mutex::new(Vec::with_capacity(ELEMENTS.len())));
+ let tree2 = Arc::clone(&tree);
+
+ let mp2 = Arc::clone(&mp);
+ let _ = thread::spawn(move || {
+ let mut rng = ThreadRng::default();
+ pb_main.tick();
+ loop {
+ thread::sleep(Duration::from_millis(15));
+ match get_action(&mut rng, &tree) {
+ None => {
+ // all elements were exhausted
+ pb_main.finish();
+ return;
+ }
+ Some(Action::AddProgressBar(el_idx)) => {
+ let elem = &ELEMENTS[el_idx];
+ let pb = mp2.insert(elem.index + 1, elem.progress_bar.clone());
+ pb.set_message(format!("{} {}", " ".repeat(elem.indent), elem.key));
+ tree.lock().unwrap().insert(elem.index, elem);
+ }
+ Some(Action::IncProgressBar(el_idx)) => {
+ let elem = &tree.lock().unwrap()[el_idx];
+ elem.progress_bar.inc(1);
+ let pos = elem.progress_bar.position();
+ if pos >= elem.progress_bar.length().unwrap() {
+ elem.progress_bar.finish_with_message(format!(
+ "{}{} {}",
+ " ".repeat(elem.indent),
+ "✔",
+ elem.key
+ ));
+ }
+ pb_main.inc(1);
+ }
+ }
+ }
+ })
+ .join();
+
+ println!("===============================");
+ println!("the tree should be the same as:");
+ for elem in tree2.lock().unwrap().iter() {
+ println!("{} {}", " ".repeat(elem.indent), elem.key);
+ }
+}
+
+/// The function guarantees to return the action, that is valid for the current tree.
+fn get_action(rng: &mut dyn RngCore, tree: &Mutex<Vec<&Elem>>) -> Option<Action> {
+ let elem_len = ELEMENTS.len() as u64;
+ let list_len = tree.lock().unwrap().len() as u64;
+ let sum_free = tree
+ .lock()
+ .unwrap()
+ .iter()
+ .map(|e| {
+ let pos = e.progress_bar.position();
+ let len = e.progress_bar.length().unwrap();
+ len - pos
+ })
+ .sum::<u64>();
+
+ if sum_free == 0 && list_len == elem_len {
+ // nothing to do more
+ None
+ } else if sum_free == 0 && list_len < elem_len {
+ // there is no place to make an increment
+ Some(Action::AddProgressBar(tree.lock().unwrap().len()))
+ } else {
+ loop {
+ let list = tree.lock().unwrap();
+ let k = rng.gen_range(0..17);
+ if k == 0 && list_len < elem_len {
+ return Some(Action::AddProgressBar(list.len()));
+ } else {
+ let l = (k % list_len) as usize;
+ let pos = list[l].progress_bar.position();
+ let len = list[l].progress_bar.length();
+ if pos < len.unwrap() {
+ return Some(Action::IncProgressBar(l));
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/indicatif/examples/multi.rs b/vendor/indicatif/examples/multi.rs
new file mode 100644
index 000000000..5ec6c5ccf
--- /dev/null
+++ b/vendor/indicatif/examples/multi.rs
@@ -0,0 +1,67 @@
+use std::thread;
+use std::time::Duration;
+
+use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
+
+use rand::Rng;
+
+fn main() {
+ let m = MultiProgress::new();
+ let sty = ProgressStyle::with_template(
+ "[{elapsed_precise}] {bar:40.cyan/blue} {pos:>7}/{len:7} {msg}",
+ )
+ .unwrap()
+ .progress_chars("##-");
+
+ let n = 200;
+ let pb = m.add(ProgressBar::new(n));
+ pb.set_style(sty.clone());
+ pb.set_message("todo");
+ let pb2 = m.add(ProgressBar::new(n));
+ pb2.set_style(sty.clone());
+ pb2.set_message("finished");
+
+ let pb3 = m.insert_after(&pb2, ProgressBar::new(1024));
+ pb3.set_style(sty);
+
+ m.println("starting!").unwrap();
+
+ let mut threads = vec![];
+
+ let m_clone = m.clone();
+ let h3 = thread::spawn(move || {
+ for i in 0..1024 {
+ thread::sleep(Duration::from_millis(2));
+ pb3.set_message(format!("item #{}", i + 1));
+ pb3.inc(1);
+ }
+ m_clone.println("pb3 is done!").unwrap();
+ pb3.finish_with_message("done");
+ });
+
+ for i in 0..n {
+ thread::sleep(Duration::from_millis(15));
+ if i == n / 3 {
+ thread::sleep(Duration::from_secs(2));
+ }
+ pb.inc(1);
+ let m = m.clone();
+ let pb2 = pb2.clone();
+ threads.push(thread::spawn(move || {
+ let spinner = m.add(ProgressBar::new_spinner().with_message(i.to_string()));
+ spinner.enable_steady_tick(Duration::from_millis(100));
+ thread::sleep(
+ rand::thread_rng().gen_range(Duration::from_secs(1)..Duration::from_secs(5)),
+ );
+ pb2.inc(1);
+ }));
+ }
+ pb.finish_with_message("all jobs started");
+
+ for thread in threads {
+ let _ = thread.join();
+ }
+ let _ = h3.join();
+ pb2.finish_with_message("all jobs done");
+ m.clear().unwrap();
+}
diff --git a/vendor/indicatif/examples/single.rs b/vendor/indicatif/examples/single.rs
new file mode 100644
index 000000000..6e921e54f
--- /dev/null
+++ b/vendor/indicatif/examples/single.rs
@@ -0,0 +1,13 @@
+use std::thread;
+use std::time::Duration;
+
+use indicatif::ProgressBar;
+
+fn main() {
+ let pb = ProgressBar::new(1024);
+ for _ in 0..1024 {
+ thread::sleep(Duration::from_millis(5));
+ pb.inc(1);
+ }
+ pb.finish_with_message("done");
+}
diff --git a/vendor/indicatif/examples/slow.rs b/vendor/indicatif/examples/slow.rs
new file mode 100644
index 000000000..91a8e7e60
--- /dev/null
+++ b/vendor/indicatif/examples/slow.rs
@@ -0,0 +1,12 @@
+use indicatif::{ProgressBar, ProgressStyle};
+use std::time::Duration;
+
+fn main() {
+ let progress =
+ ProgressBar::new(10).with_style(ProgressStyle::default_bar().progress_chars("🔐🔑🕓"));
+ for _ in 0..10 {
+ progress.inc(1);
+ std::thread::sleep(Duration::from_secs(1));
+ }
+ progress.finish();
+}
diff --git a/vendor/indicatif/examples/spinner-loop.rs b/vendor/indicatif/examples/spinner-loop.rs
new file mode 100644
index 000000000..14d698b43
--- /dev/null
+++ b/vendor/indicatif/examples/spinner-loop.rs
@@ -0,0 +1,18 @@
+use std::thread;
+use std::time::Duration;
+
+use indicatif::{ProgressBar, ProgressFinish};
+
+fn main() {
+ let mut spinner: Option<ProgressBar> = None;
+
+ for i in 0..3 {
+ let new_spinner = ProgressBar::new_spinner()
+ .with_message(format!("doing stuff {}", i))
+ .with_finish(ProgressFinish::AndLeave);
+ new_spinner.enable_steady_tick(Duration::from_millis(10));
+ thread::sleep(Duration::from_millis(500));
+ println!("\n\nreplace {}\n\n", i);
+ spinner.replace(new_spinner).map(|t| t.finish());
+ }
+}
diff --git a/vendor/indicatif/examples/steady.rs b/vendor/indicatif/examples/steady.rs
new file mode 100644
index 000000000..4515ce97b
--- /dev/null
+++ b/vendor/indicatif/examples/steady.rs
@@ -0,0 +1,50 @@
+use std::{
+ thread::sleep,
+ time::{Duration, Instant},
+};
+
+use indicatif::{ProgressBar, ProgressIterator, ProgressStyle};
+
+fn main() {
+ let iterations = 1000;
+ // Set the array with all the blocksizes to test
+ let blocksizes: [usize; 7] = [16, 64, 256, 1024, 4096, 16384, 65536];
+
+ // Set the array with all the durations to save
+ let mut elapsed: [Duration; 7] = [Duration::ZERO; 7];
+
+ for (pos, blocksize) in blocksizes.iter().enumerate() {
+ // Set up the style for the progressbar
+ let sty = ProgressStyle::default_spinner()
+ .tick_strings(&[
+ "▹▹▹▹▹",
+ "▸▹▹▹▹",
+ "▹▸▹▹▹",
+ "▹▹▸▹▹",
+ "▹▹▹▸▹",
+ "▹▹▹▹▸",
+ "▪▪▪▪▪",
+ ])
+ .template("{prefix} {pos:>4}/{len:4} Iterations per second: {per_sec} {spinner} {msg}")
+ .unwrap();
+
+ // Set up the progress bar and apply the style
+ let pb = ProgressBar::new(iterations);
+ pb.set_style(sty);
+ pb.enable_steady_tick(Duration::from_millis(120));
+ pb.set_prefix(format!("Doing test with Blocksize {:5?}:", blocksize));
+
+ // Iterate for the given number of iterations
+ // for _ in (0..iterations) {
+ for _ in (0..iterations).progress_with(pb) {
+ // pb.inc(1);
+ // Take a timestamp for timemeasurement later on
+ let now = Instant::now();
+ sleep(Duration::from_millis(1));
+ // Save the elapsed time for later evaluation
+ elapsed[pos] += now.elapsed();
+ }
+
+ // pb.finish_using_style();
+ }
+}
diff --git a/vendor/indicatif/examples/tokio.rs b/vendor/indicatif/examples/tokio.rs
new file mode 100644
index 000000000..17ac2b1ff
--- /dev/null
+++ b/vendor/indicatif/examples/tokio.rs
@@ -0,0 +1,34 @@
+use std::time::Duration;
+
+use indicatif::ProgressBar;
+use tokio::runtime;
+use tokio::time::interval;
+
+fn main() {
+ // Plain progress bar, totaling 1024 steps.
+ let steps = 1024;
+ let pb = ProgressBar::new(steps);
+
+ // Stream of events, triggering every 5ms.
+ let rt = runtime::Builder::new_current_thread()
+ .enable_time()
+ .build()
+ .expect("failed to create runtime");
+
+ // Future computation which runs for `steps` interval events,
+ // incrementing one step of the progress bar each time.
+ let future = async {
+ let mut intv = interval(Duration::from_millis(5));
+
+ for _ in 0..steps {
+ intv.tick().await;
+ pb.inc(1);
+ }
+ };
+
+ // Drive the future to completion, blocking until done.
+ rt.block_on(future);
+
+ // Mark the progress bar as finished.
+ pb.finish();
+}
diff --git a/vendor/indicatif/examples/yarnish.rs b/vendor/indicatif/examples/yarnish.rs
new file mode 100644
index 000000000..6b7c29b1a
--- /dev/null
+++ b/vendor/indicatif/examples/yarnish.rs
@@ -0,0 +1,97 @@
+use std::thread;
+use std::time::{Duration, Instant};
+
+use console::{style, Emoji};
+use indicatif::{HumanDuration, MultiProgress, ProgressBar, ProgressStyle};
+use rand::seq::SliceRandom;
+use rand::Rng;
+
+static PACKAGES: &[&str] = &[
+ "fs-events",
+ "my-awesome-module",
+ "emoji-speaker",
+ "wrap-ansi",
+ "stream-browserify",
+ "acorn-dynamic-import",
+];
+
+static COMMANDS: &[&str] = &[
+ "cmake .",
+ "make",
+ "make clean",
+ "gcc foo.c -o foo",
+ "gcc bar.c -o bar",
+ "./helper.sh rebuild-cache",
+ "make all-clean",
+ "make test",
+];
+
+static LOOKING_GLASS: Emoji<'_, '_> = Emoji("🔍 ", "");
+static TRUCK: Emoji<'_, '_> = Emoji("🚚 ", "");
+static CLIP: Emoji<'_, '_> = Emoji("🔗 ", "");
+static PAPER: Emoji<'_, '_> = Emoji("📃 ", "");
+static SPARKLE: Emoji<'_, '_> = Emoji("✨ ", ":-)");
+
+pub fn main() {
+ let mut rng = rand::thread_rng();
+ let started = Instant::now();
+ let spinner_style = ProgressStyle::with_template("{prefix:.bold.dim} {spinner} {wide_msg}")
+ .unwrap()
+ .tick_chars("⠁⠂⠄⡀⢀⠠⠐⠈ ");
+
+ println!(
+ "{} {}Resolving packages...",
+ style("[1/4]").bold().dim(),
+ LOOKING_GLASS
+ );
+ println!(
+ "{} {}Fetching packages...",
+ style("[2/4]").bold().dim(),
+ TRUCK
+ );
+
+ println!(
+ "{} {}Linking dependencies...",
+ style("[3/4]").bold().dim(),
+ CLIP
+ );
+ let deps = 1232;
+ let pb = ProgressBar::new(deps);
+ for _ in 0..deps {
+ thread::sleep(Duration::from_millis(3));
+ pb.inc(1);
+ }
+ pb.finish_and_clear();
+
+ println!(
+ "{} {}Building fresh packages...",
+ style("[4/4]").bold().dim(),
+ PAPER
+ );
+ let m = MultiProgress::new();
+ let handles: Vec<_> = (0..4u32)
+ .map(|i| {
+ let count = rng.gen_range(30..80);
+ let pb = m.add(ProgressBar::new(count));
+ pb.set_style(spinner_style.clone());
+ pb.set_prefix(format!("[{}/?]", i + 1));
+ thread::spawn(move || {
+ let mut rng = rand::thread_rng();
+ let pkg = PACKAGES.choose(&mut rng).unwrap();
+ for _ in 0..count {
+ let cmd = COMMANDS.choose(&mut rng).unwrap();
+ thread::sleep(Duration::from_millis(rng.gen_range(25..200)));
+ pb.set_message(format!("{pkg}: {cmd}"));
+ pb.inc(1);
+ }
+ pb.finish_with_message("waiting...");
+ })
+ })
+ .collect();
+ for h in handles {
+ let _ = h.join();
+ }
+ m.clear().unwrap();
+
+ println!("{} Done in {}", SPARKLE, HumanDuration(started.elapsed()));
+}