diff --git a/src/benchmark/mod.rs b/src/benchmark/mod.rs index c7978b8bd..e0bee747f 100644 --- a/src/benchmark/mod.rs +++ b/src/benchmark/mod.rs @@ -10,7 +10,9 @@ use crate::command::Command; use crate::options::{CmdFailureAction, ExecutorKind, Options, OutputStyleOption}; use crate::outlier_detection::{modified_zscores, OUTLIER_THRESHOLD}; use crate::output::format::{format_duration, format_duration_unit}; -use crate::output::progress_bar::get_progress_bar; +use crate::output::progress_bar::{ + get_progress_bar, replace_message_template, reset_progress_template, +}; use crate::output::warnings::Warnings; use crate::parameter::ParameterNameAndValue; use crate::util::exit_code::extract_exit_code; @@ -175,11 +177,13 @@ impl<'a> Benchmark<'a> { // Set up progress bar (and spinner for initial measurement) let progress_bar = if self.options.output_style != OutputStyleOption::Disabled { - Some(get_progress_bar( + let temp_bar = get_progress_bar( self.options.run_bounds.min, - "Initial time measurement", + "Initial time measurement:", self.options.output_style, - )) + ); + let template = format!("{{msg}} {{elapsed:<{}}}", 30 - temp_bar.message().len() - 1,); + Some(replace_message_template(temp_bar, &template)) } else { None }; @@ -219,6 +223,7 @@ impl<'a> Benchmark<'a> { all_succeeded = all_succeeded && success; // Re-configure the progress bar + let progress_bar = progress_bar.map(reset_progress_template); if let Some(bar) = progress_bar.as_ref() { bar.set_length(count) } diff --git a/src/output/progress_bar.rs b/src/output/progress_bar.rs index add9a8007..c655a2dab 100644 --- a/src/output/progress_bar.rs +++ b/src/output/progress_bar.rs @@ -9,13 +9,42 @@ const TICK_SETTINGS: (&str, u64) = ("⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏ ", 80); #[cfg(windows)] const TICK_SETTINGS: (&str, u64) = (r"+-x| ", 200); +const DEFAULT_MESSAGE_TEMPLATE: &str = "{msg:<30}"; + +fn create_progress_template(msg_template: &str) -> String { + format!( + " {{spinner}} {} {{wide_bar}} ETA {{eta_precise}}", + msg_template + ) +} + +/// Replace the usual `message` in a progress bar with the result of evaluating `template`. +/// The `template` may contain a `ProgressBar`'s templated fields. +#[must_use] +pub fn replace_message_template(bar: ProgressBar, template: &str) -> ProgressBar { + let old_style = bar.style(); + let new_template = create_progress_template(template); + let new_style = old_style + .template(&new_template) + .expect("no template error"); + bar.with_style(new_style) +} + +/// Reset a progress bar's template to the default. +/// This is useful after calling `replace_message_template()`. +#[must_use] +pub fn reset_progress_template(bar: ProgressBar) -> ProgressBar { + replace_message_template(bar, DEFAULT_MESSAGE_TEMPLATE) +} + /// Return a pre-configured progress bar pub fn get_progress_bar(length: u64, msg: &str, option: OutputStyleOption) -> ProgressBar { + let template = create_progress_template(DEFAULT_MESSAGE_TEMPLATE); let progressbar_style = match option { OutputStyleOption::Basic | OutputStyleOption::Color => ProgressStyle::default_bar(), _ => ProgressStyle::default_spinner() .tick_chars(TICK_SETTINGS.0) - .template(" {spinner} {msg:<30} {wide_bar} ETA {eta_precise}") + .template(&template) .expect("no template error"), };