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(); }