|
|
|
@ -1,15 +1,19 @@ |
|
|
|
|
//! Fancy progress bar functionality.
|
|
|
|
|
|
|
|
|
|
use console::style; |
|
|
|
|
use emoji; |
|
|
|
|
use indicatif::{ProgressBar, ProgressStyle}; |
|
|
|
|
use parking_lot::RwLock; |
|
|
|
|
use std::fmt; |
|
|
|
|
|
|
|
|
|
/// Synchronized progress bar and status message printing.
|
|
|
|
|
pub struct ProgressOutput { |
|
|
|
|
spinner: RwLock<ProgressBar>, |
|
|
|
|
messages: RwLock<String>, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl ProgressOutput { |
|
|
|
|
/// Construct a new `ProgressOutput`.
|
|
|
|
|
pub fn new() -> Self { |
|
|
|
|
Self { |
|
|
|
|
spinner: RwLock::new(ProgressBar::new_spinner()), |
|
|
|
@ -17,6 +21,8 @@ impl ProgressOutput { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Inform the user that the given `step` is being executed, with details in
|
|
|
|
|
/// `message`.
|
|
|
|
|
pub fn step(&self, step: &Step, message: &str) { |
|
|
|
|
let msg = format!("{} {}", style(step).bold().dim(), message); |
|
|
|
|
self.message(&msg) |
|
|
|
@ -31,6 +37,7 @@ impl ProgressOutput { |
|
|
|
|
message.clear(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Print the given message.
|
|
|
|
|
pub fn message(&self, message: &str) { |
|
|
|
|
self.finish(); |
|
|
|
|
|
|
|
|
@ -45,6 +52,7 @@ impl ProgressOutput { |
|
|
|
|
message.push('\n'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Add an informational message.
|
|
|
|
|
pub fn info(&self, message: &str) { |
|
|
|
|
let info = format!( |
|
|
|
|
"{} {}: {}", |
|
|
|
@ -55,6 +63,7 @@ impl ProgressOutput { |
|
|
|
|
self.add_message(&info); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Add a warning message.
|
|
|
|
|
pub fn warn(&self, message: &str) { |
|
|
|
|
let warn = format!( |
|
|
|
|
"{} {}: {}", |
|
|
|
@ -65,6 +74,7 @@ impl ProgressOutput { |
|
|
|
|
self.add_message(&warn); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Add an error message.
|
|
|
|
|
pub fn error(&self, message: String) { |
|
|
|
|
let err = format!( |
|
|
|
|
"{} {}: {}", |
|
|
|
@ -87,20 +97,28 @@ impl ProgressOutput { |
|
|
|
|
pb |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// After having built up a series of messages, print all of them out.
|
|
|
|
|
pub fn done(&self) { |
|
|
|
|
self.finish(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// For processes that can be broken down into N fractional steps, with messages
|
|
|
|
|
/// added for each step along the way like
|
|
|
|
|
///
|
|
|
|
|
/// > [2/5] Doing the second step out of five.
|
|
|
|
|
pub struct Step { |
|
|
|
|
current: usize, |
|
|
|
|
total: usize, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl Step { |
|
|
|
|
/// Construct a `Step` where there are `total` number of steps.
|
|
|
|
|
pub fn new(total: usize) -> Step { |
|
|
|
|
Step { current: 1, total } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Increment the current step.
|
|
|
|
|
pub fn inc(&mut self) { |
|
|
|
|
self.current += 1; |
|
|
|
|
} |
|
|
|
|