Skip to content

kotet/progress

Repository files navigation

progress

D Dub version Go to progress LICENSE

Easy progress reporting for D inspired by Python's one with the same name.
There are 6 progress bar, 4 spinner, 4 counter, and... Dman.

Progress bar

  • Bar
  • ChargingBar
  • FillingSquaresBar
  • FillingCirclesBar
  • IncrementalBat
  • ShadyBar

Spinner

  • Spinner
  • PieSpinner
  • MoonSpinner
  • LineSpinner

Counter

  • Counter
  • Countdown
  • Stack
  • Pie

Dman

  • DmanSpinner

Usage

progress bars

Call next to advance and finish to finish.

Bar b = new Bar();
b.message = {return "Processing";};
b.max = 20;
foreach(i; 0 .. 20)
{
    //Do some work
    b.next();
}
b.finish();
Processing |##################              | 12/20

In the general case, you can use the iter method to write simply

import std.range : iter;

Bar b = new Bar();
foreach(i; b.iter(iota(20)) )
{
    //Do something
}

Progress bars are very customizable, you can change their width, their fill character, their suffix and more.

import std.conv : to;

b.message = {return "Loading";};
b.fill = '@';
b.suffix = {return b.percent.to!string ~ "%";};

This will produce a bar like the following:

Loading |@@@@@@@                         | 24%

There are various properties that can be used in message and suffix.

name type value
index size_t current value
max size_t maximum value
remaining size_t max - index
progress real index / max
percent real progress * 100
avg Duration simple moving average time per item
elapsed Duration elapsed time in seconds
eta Duration avg * remaining

Instead of passing all configuration options on instatiation, you can create your custom subclass:

class CustomBar : Bar
{
    this()
    {
        super();
        bar_prefix = "/";
        bar_suffix = "/";
        empty_fill = " ";
        fill = "/";
        suffix = {return "Custom";};
    }

You can also override any of the arguments or create your own:

class SlowBar : Bar
{
    this()
    {
        super();
        suffix = {return this.remaining_hours.to!string ~ "hours remaining";};
    }
    @property long remaining_hours()
    {
        return this.eta.total!"hours";
    }
}

Spinners

For actions with an unknown number of steps you can use a spinner:

import progress.spinner;

auto s = new Spinner();
s.message = {return "Loading";};
while (finished != true)
{
    //Do something
    s.next();
}

Counters

Counters can be used like progress bar.
However, Counter is the same as spinners, and has no properties that require maximum value.

Dman

Same as spinners. it's very big.


Please see example projects and source if you want to learn more.