Initial vendor packages
Signed-off-by: Valentin Popov <valentin@popov.link>
This commit is contained in:
189
vendor/indicatif/examples/multi-tree.rs
vendored
Normal file
189
vendor/indicatif/examples/multi-tree.rs
vendored
Normal file
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user