Progress bar for while loop

Hi, I am trying to find a way to add a progress bar inside a while loop using either a crate like indicatif or other codes. Can you please point me to an option to do it? Thanks.

Have you looked through indicatif's examples folder?

The download.rs example seems to do what you want.

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::default_bar()
        .template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})")
        .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");
}

Sorry to not have specified it in my answer but, to create a progress bar in all options I've seen I need to know in advance the total or size to define the progress bar. I want to add a progress bar that can be used in a while loop without knowing in advance the number of iteration. In python tqdm I have a solution.

Looking at the accepted solution it seems like you still need to give tqdm a total (i.e. with tqdm(total=100) as pbar: ...).

Taking a step back, progress bars are usually used to indicate the proportion of a task that has been completed so far, and in order to say how much has been done you naturally need to know how much work there is in total.

If you just want to indicate that progress is being made and print some sort of "status" message so the user knows what is being done at the moment, I'd try their spinner example.

Alternatively, if you don't know the total amount of work up front but can steadily revise it as your application progresses, you could continually update the length (i.e. ProgressBar::set_length()). From a UX perspective that isn't great because it looks like you keep making progress only to be knocked back, and there is no way of knowing how many times you'll be knocked back until the task is complete, but it sounds closer to what you want.

You can also use their iterator example.

use indicatif::{ProgressBar, ProgressIterator, ProgressStyle};

fn main() {
    // Default styling, attempt to use Iterator::size_hint to count input size
    for _ in (0..1000).progress() {
        // ...
    }
}
1 Like

Thanks!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.