diff --git a/src/benchmark/mod.rs b/src/benchmark/mod.rs index c0d3eac..958e2ba 100644 --- a/src/benchmark/mod.rs +++ b/src/benchmark/mod.rs @@ -14,7 +14,9 @@ use crate::options::{ }; use crate::outlier_detection::OUTLIER_THRESHOLD; use crate::output::console_writeln; -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::{OutlierWarningOptions, Warnings}; use crate::parameter::ParameterNameAndValue; use crate::quantity::{const_time_from_seconds, ratio, FormatQuantity, Time, Zero}; @@ -242,11 +244,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 }; @@ -298,6 +302,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 ff91cd0..fd9f4ca 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} Time: {elapsed} ETA {eta_precise} ") + .template(&template) .expect("no template error"), };