pub struct Progless { /* private fields */ }progress only.Expand description
§Progless.
This is a simple, thread-safe, steady-ticking CLI progress bar that can be used to entertain users while long jobs are running.
To use it, enable the progress crate flag.
§Examples
Initialize and use as follows:
use fyi_msg::Progless;
// You can use [`Progless::try_from`] for any unsigned integer type, or the
// infallible [`Progless::from`] on an [`std::num::NonZeroU32`].
let pbar = Progless::try_from(1001_u32).unwrap();
// Iterate your taskwork or whatever.
for i in 0..1001 {
// Do some work.
// ...
// Increment the count.
pbar.increment();
}
// Close it off.
pbar.finish();Progless is thread-safe so can be called from parallel iterators like
those from rayon without any special fuss.
When doing parallel work, many tasks might be “in progress” simultaneously.
To that end, you may wish to use the Progless::add and Progless::remove
methods at the start and end of each iteration instead of manually
incrementing the counts.
Doing this, a list of active tasks will be maintained and printed along
with the progress. Removing a task automatically increments the done count,
so if you’re tracking tasks, you should not call Progless::increment.
// ... snip
// Iterate in Parallel.
(0..1001).into_par_iter().for_each(|i| {
let task: String = format!("Task #{}.", i);
pbar.add(&task);
// Do some work.
pbar.remove(&task);
});
// ... snipImplementations§
Source§impl Progless
impl Progless
Sourcepub fn sigint_two_strike() -> &'static Arc<AtomicBool>
Available on crate feature signals_sigint only.
pub fn sigint_two_strike() -> &'static Arc<AtomicBool>
signals_sigint only.§Two-Strike SIGINT Handler.
Implement a two-strike SIGINT-handling policy, performing some
cleanup if and when the first signal is received, but only dying if
there’s a second.
The returned state variable can be used to check whether or not a
SIGINT has come in, and change course accordingly.
§Warnings
SIGINT-handling strategies are mutually exclusive and custom
bindings are not supported.
This library offers three different options — default, two-strike, and keepalive — and implements whichever happens to be registered first.
As such, this method should be called as early as possible, and before
any Progless instances are created, otherwise you’ll be stuck with
the default “immediate death” handling.
§Examples
use fyi_msg::Progless;
use std::sync::atomic::Ordering::SeqCst;
// Register a shutdown handler.
let killed = Progless::sigint_two_strike();
loop {
// CTRL+C was pressed once. Clean up and apologize!
if killed.load(SeqCst) {
eprintln!("So long and thanks for the fish!");
return;
}
// Do stuff as usual…
}§Panics
This will panic if the handler cannot be registered for whatever reason. If another handler was already present, it will simply return its switch instead.
Sourcepub fn sigint_keepalive() -> &'static Arc<AtomicBool>
Available on crate feature signals_sigint only.
pub fn sigint_keepalive() -> &'static Arc<AtomicBool>
signals_sigint only.§Keepalive SIGINT Handler.
Implement a keepalive SIGINT-handling policy, performing some
cleanup if and when the first signal is received, without triggering
any early exit. (The program will keep on keeping on.)
The returned state variable can be used to check whether or not a
SIGINT has come in, and change course accordingly.
§Warnings
SIGINT-handling strategies are mutually exclusive and custom
bindings are not supported.
This library offers three different options — default, two-strike, and keepalive — and implements whichever happens to be registered first.
As such, this method should be called as early as possible, and before
any Progless instances are created, otherwise you’ll be stuck with
the default “immediate death” handling.
§Examples
use fyi_msg::Progless;
use std::sync::atomic::Ordering::SeqCst;
// Register a non-shutdown shutdown handler.
let killed = Progless::sigint_keepalive();
let mut warned = false;
loop {
// The first CTRL+C has arrived.
if ! warned && killed.load(SeqCst) {
warned = true;
eprintln!("I hear you, but do not care!");
}
// Do stuff as usual…
}§Panics
This will panic if the handler cannot be registered for whatever reason. If another handler was already present, it will simply return its switch instead.
Source§impl Progless
§Constants.
impl Progless
§Constants.
Sourcepub const CURSOR_HIDE: &str = "\x1b[?25l"
pub const CURSOR_HIDE: &str = "\x1b[?25l"
Sourcepub const CURSOR_UNHIDE: &str = "\x1b[?25h"
pub const CURSOR_UNHIDE: &str = "\x1b[?25h"
Sourcepub const MAX_TOTAL_ERROR: ProglessError = ProglessError::TotalOverflow
pub const MAX_TOTAL_ERROR: ProglessError = ProglessError::TotalOverflow
Source§impl Progless
§Construction/Destruction.
impl Progless
§Construction/Destruction.
Sourcepub fn with_title<S>(self, title: Option<S>) -> Self
pub fn with_title<S>(self, title: Option<S>) -> Self
§With Title.
Add a title to the progress bar. When present, this will print on its own line immediately before the progress line.
Titles are formatted as Msg objects. You can pass a Msg
directly, or something that can be converted to one, like a string
slice.
Pass None to remove the title entirely.
Note: titles cannot have line breaks; this will automatically replace any non-space whitespace with regular horizontal spaces.
§Examples
use fyi_msg::{Msg, Progless};
// Initialize with a `u32` total.
let pbar = Progless::try_from(1001_u32).unwrap()
.with_title(Some(Msg::info("Doing things!")));
// Iterate your taskwork or whatever.
for i in 0..1001 {
// Do some work.
// ...
// Increment the done count.
pbar.increment();
}
pbar.finish();Sourcepub fn with_reticulating_splines<S>(self, app: S) -> Self
pub fn with_reticulating_splines<S>(self, app: S) -> Self
§Set Title As X: Reticulating Splines…
This is simply shorthand for generating a “Reticulating Splines…” title, where X is the value passed in (usually the app name).
It’s a sort of default…
Sourcepub fn finish(&self) -> Duration
pub fn finish(&self) -> Duration
§Stop.
Finish the progress bar, shut down the steady ticker, and return the time elapsed.
Calling this method will also erase any previously-printed progress information from the CLI screen.
§Examples
use fyi_msg::Progless;
// Initialize with a `u32` total.
let pbar = Progless::try_from(1001_u32).unwrap();
// Iterate your taskwork or whatever.
for i in 0..1001 {
// Do some work.
// ...
// Increment the done count.
pbar.increment();
}
// Finish it off!
pbar.finish();Sourcepub fn summary<S>(&self, kind: MsgKind, singular: S, plural: S) -> Msg
pub fn summary<S>(&self, kind: MsgKind, singular: S, plural: S) -> Msg
§Summarize.
Generate a formatted Msg summary of the (finished) progress using
the supplied verb and noun.
If you just want a generic “Finished in X.” message, use Msg::from
instead.
Note: if you called Progless::reset anywhere along the way, this
won’t include totals from the previous run(s). (The duration is the
only constant.)
§Examples
use fyi_msg::{MsgKind, Progless};
// Initialize with a `u32` total.
let pbar = Progless::try_from(1001_u32).unwrap();
// Iterate your taskwork or whatever.
for i in 0..1001 {
// Do some work.
// ...
// Increment the done count.
pbar.increment();
}
pbar.finish();
// Print something like "Crunched X files in Y seconds."
pbar.summary(MsgKind::Crunched, "file", "files").print();Source§impl Progless
§Passthrough Setters.
impl Progless
§Passthrough Setters.
Sourcepub fn add<S>(&self, txt: S) -> bool
pub fn add<S>(&self, txt: S) -> bool
§Add a task.
The progress bar can optionally keep track of tasks that are actively “in progress”, which can be particularly useful when operating in parallel.
Any AsRef<str> value will do. See the module documentation for
example usage.
Returns true if the task was accepted. (If false, you should use
Progless::increment to mark the task as done instead of
Progless::remove.)
§Examples
use fyi_msg::Progless;
// Initialize with a `u32` total.
let pbar = Progless::try_from(1001_u32).unwrap();
// Iterate your taskwork or whatever.
for i in 0..1001 {
let task: String = format!("Task #{}.", i);
pbar.add(&task);
// Do some work.
pbar.remove(&task);
}
pbar.finish();Sourcepub fn increment(&self)
pub fn increment(&self)
§Increment Done.
Increase the completed count by exactly one. This is safer to use than
set_done() in cases where multiple tasks are happening at once as it
will not accidentally decrease the value, etc.
See the various examples all over this page for more information.
Sourcepub fn increment_n(&self, n: u32)
pub fn increment_n(&self, n: u32)
§Increment Done by N.
Increase the completed count by n. This is safer to use than set_done()
and more efficient than calling increment() a million times in a row.
Sourcepub fn push_msg(&self, msg: Msg) -> Result<(), Msg>
pub fn push_msg(&self, msg: Msg) -> Result<(), Msg>
§Push Message.
“Insert” (print) a line (to STDERR) above the running progress bar,
useful for realtime debug logs, warnings, etc., that would otherwise
have to wait for the Progless instance to finish hogging the
display.
§Errors
In practice this should never fail, but if for some reason STDERR is tied up the original message is passed back as an error in case you want to try to deal with it yourself.
Sourcepub fn remove<S>(&self, txt: S)
pub fn remove<S>(&self, txt: S)
§Remove a task.
This is the equal and opposite companion to Progless::add. Calling
this will automatically increment the done count by one, so should not
be used in cases where you’re triggering done changes manually.
See Progless::add for more details. If you use one, you must use
both.
Sourcepub fn reset(&self, total: NonZeroU32)
pub fn reset(&self, total: NonZeroU32)
§Reset.
Stop the current run (if any), clear the done/doing metrics, and assign
a new total so you can re-use the Progless instance for a new set
of tasks.
Note: the start/elapsed times for a given Progless instance are
continuous. If you need the time counter to reset to [00:00:00],
you need start a brand new instance instead of resetting an existing
one.
Sourcepub fn try_reset(&self, total: u32) -> Result<(), ProglessError>
pub fn try_reset(&self, total: u32) -> Result<(), ProglessError>
§Reset (Fallible).
Same as Progless::reset, but will fail if total is zero.
§Errors
This will return an error if the new total is zero.
Sourcepub fn set_done(&self, done: u32)
pub fn set_done(&self, done: u32)
§Set Done.
Set the done count to a specific value.
In general, you should either use Progless::add/Progless::remove
or Progless::increment rather than this method, as they ensure any
changes made are relative.
This method overrides the done value instead, so can cause regressions if you’re doing task work in parallel and one thread finishes before another, etc.
Sourcepub fn set_title<S>(&self, title: Option<S>)
pub fn set_title<S>(&self, title: Option<S>)
§Set Title.
Give the progress bar a title, which will be shown above the progress bits while progress is progressing, and removed afterward with everything else.
See Progless::with_title for more details.
Sourcepub fn set_title_msg(&self, msg: &str)
pub fn set_title_msg(&self, msg: &str)
§Set Title Message.
Change (only) the message part — what follows the prefix — of the title to something else.
Note: this has no effect for instances without a title component.
Sourcepub fn set_reticulating_splines<S>(&self, app: S)
pub fn set_reticulating_splines<S>(&self, app: S)
§Set Title As X: Reticulating Splines…
This is simply shorthand for generating a “Reticulating Splines…” title, where X is the value passed in (usually the app name).
It’s a sort of default…