diff --git a/src/in_memory.rs b/src/in_memory.rs index 8c5bde5c..78cdbeb9 100644 --- a/src/in_memory.rs +++ b/src/in_memory.rs @@ -131,7 +131,7 @@ impl Debug for InMemoryTermState { #[cfg(test)] mod test { use super::*; - use crate::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressFinish, ProgressStyle}; + use crate::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressFinish}; #[test] fn basic_progress_bar() { @@ -163,10 +163,7 @@ mod test { in_mem.clone(), ))); - let pb1 = mp.add( - ProgressBar::new(10) - .with_style(ProgressStyle::default_bar().on_finish(ProgressFinish::AndLeave)), - ); + let pb1 = mp.add(ProgressBar::new(10).with_finish(ProgressFinish::AndLeave)); let pb2 = mp.add(ProgressBar::new(5)); let pb3 = mp.add(ProgressBar::new(100)); diff --git a/src/lib.rs b/src/lib.rs index 510accd4..4df8d017 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -236,8 +236,8 @@ pub use crate::in_memory::InMemoryTerm; pub use crate::iter::{ProgressBarIter, ProgressIterator}; pub use crate::multi::{MultiProgress, MultiProgressAlignment}; pub use crate::progress_bar::{ProgressBar, WeakProgressBar}; -pub use crate::state::ProgressState; -pub use crate::style::{ProgressFinish, ProgressStyle}; +pub use crate::state::{ProgressFinish, ProgressState}; +pub use crate::style::ProgressStyle; pub use crate::term_like::TermLike; #[cfg(feature = "rayon")] diff --git a/src/progress_bar.rs b/src/progress_bar.rs index ed2d4179..c6e06e82 100644 --- a/src/progress_bar.rs +++ b/src/progress_bar.rs @@ -7,7 +7,7 @@ use std::thread; use std::time::{Duration, Instant}; use crate::draw_target::ProgressDrawTarget; -use crate::state::{BarState, Limit, ProgressState, Status}; +use crate::state::{BarState, Limit, ProgressFinish, ProgressState, Status}; use crate::style::ProgressStyle; use crate::{ProgressBarIter, ProgressIterator}; @@ -49,6 +49,7 @@ impl ProgressBar { ProgressBar { state: Arc::new(Mutex::new(BarState { draw_target, + on_finish: ProgressFinish::default(), style: ProgressStyle::default_bar(), state: ProgressState::new(len), })), @@ -85,6 +86,22 @@ impl ProgressBar { self } + /// Sets the finish behavior for the progress bar + /// + /// This behavior is invoked when [`ProgressBar`] or + /// [`ProgressBarIter`] completes and + /// [`ProgressBar::is_finished()`] is false. + /// If you don't want the progress bar to be automatically finished then + /// call `on_finish(None)`. + /// + /// [`ProgressBar`]: crate::ProgressBar + /// [`ProgressBarIter`]: crate::ProgressBarIter + /// [`ProgressBar::is_finished()`]: crate::ProgressBar::is_finished + pub fn with_finish(self, finish: ProgressFinish) -> ProgressBar { + self.state().on_finish = finish; + self + } + /// Creates a new spinner /// /// This spinner by default draws directly to stderr. This adds the default spinner style to it. diff --git a/src/state.rs b/src/state.rs index 1e000d97..342c58d1 100644 --- a/src/state.rs +++ b/src/state.rs @@ -5,10 +5,11 @@ use std::thread; use std::time::{Duration, Instant}; use crate::draw_target::ProgressDrawTarget; -use crate::style::{ProgressFinish, ProgressStyle}; +use crate::style::ProgressStyle; pub(crate) struct BarState { pub(crate) draw_target: ProgressDrawTarget, + pub(crate) on_finish: ProgressFinish, pub(crate) style: ProgressStyle, pub(crate) state: ProgressState, } @@ -17,7 +18,7 @@ impl BarState { /// Finishes the progress bar using the [`ProgressFinish`] behavior stored /// in the [`ProgressStyle`]. pub(crate) fn finish_using_style(&mut self, now: Instant) { - match self.style.get_on_finish() { + match &self.on_finish { ProgressFinish::AndLeave => self.finish_and_leave(now), ProgressFinish::AtCurrentPos => self.finish_at_current_pos(now), ProgressFinish::WithMessage(msg) => { @@ -344,6 +345,48 @@ impl fmt::Debug for Estimate { } } +/// Behavior of a progress bar when it is finished +/// +/// This is invoked when a [`ProgressBar`] or [`ProgressBarIter`] completes and +/// [`ProgressBar::is_finished`] is false. +/// +/// [`ProgressBar`]: crate::ProgressBar +/// [`ProgressBarIter`]: crate::ProgressBarIter +/// [`ProgressBar::is_finished`]: crate::ProgressBar::is_finished +#[derive(Clone, Debug)] +pub enum ProgressFinish { + /// Finishes the progress bar and leaves the current message + /// + /// Same behavior as calling [`ProgressBar::finish()`](crate::ProgressBar::finish). + AndLeave, + /// Finishes the progress bar at current position and leaves the current message + /// + /// Same behavior as calling [`ProgressBar::finish_at_current_pos()`](crate::ProgressBar::finish_at_current_pos). + AtCurrentPos, + /// Finishes the progress bar and sets a message + /// + /// Same behavior as calling [`ProgressBar::finish_with_message()`](crate::ProgressBar::finish_with_message). + WithMessage(Cow<'static, str>), + /// Finishes the progress bar and completely clears it (this is the default) + /// + /// Same behavior as calling [`ProgressBar::finish_and_clear()`](crate::ProgressBar::finish_and_clear). + AndClear, + /// Finishes the progress bar and leaves the current message and progress + /// + /// Same behavior as calling [`ProgressBar::abandon()`](crate::ProgressBar::abandon). + Abandon, + /// Finishes the progress bar and sets a message, and leaves the current progress + /// + /// Same behavior as calling [`ProgressBar::abandon_with_message()`](crate::ProgressBar::abandon_with_message). + AbandonWithMessage(Cow<'static, str>), +} + +impl Default for ProgressFinish { + fn default() -> Self { + Self::AndClear + } +} + fn duration_to_secs(d: Duration) -> f64 { d.as_secs() as f64 + f64::from(d.subsec_nanos()) / 1_000_000_000f64 } diff --git a/src/style.rs b/src/style.rs index 2dfc9177..58d269e7 100644 --- a/src/style.rs +++ b/src/style.rs @@ -1,4 +1,3 @@ -use std::borrow::Cow; use std::collections::HashMap; use std::fmt::{self, Write}; use std::mem; @@ -18,7 +17,6 @@ pub struct ProgressStyle { tick_strings: Vec>, progress_chars: Vec>, template: Template, - on_finish: ProgressFinish, // how unicode-big each char in progress_chars is char_width: usize, format_map: HashMap<&'static str, fn(&ProgressState) -> String>, @@ -83,7 +81,6 @@ impl ProgressStyle { progress_chars, char_width, template: Template::from_str(template), - on_finish: ProgressFinish::default(), format_map: HashMap::default(), } } @@ -142,22 +139,6 @@ impl ProgressStyle { self } - /// Sets the finish behavior for the progress bar - /// - /// This behavior is invoked when [`ProgressBar`] or - /// [`ProgressBarIter`] completes and - /// [`ProgressBar::is_finished()`] is false. - /// If you don't want the progress bar to be automatically finished then - /// call `on_finish(None)`. - /// - /// [`ProgressBar`]: crate::ProgressBar - /// [`ProgressBarIter`]: crate::ProgressBarIter - /// [`ProgressBar::is_finished()`]: crate::ProgressBar::is_finished - pub fn on_finish(mut self, finish: ProgressFinish) -> ProgressStyle { - self.on_finish = finish; - self - } - pub(crate) fn current_tick_str(&self, state: &ProgressState) -> &str { match state.is_finished() { true => self.get_final_tick_str(), @@ -175,11 +156,6 @@ impl ProgressStyle { &self.tick_strings[self.tick_strings.len() - 1] } - /// Returns the finish behavior - pub fn get_on_finish(&self) -> &ProgressFinish { - &self.on_finish - } - fn format_bar(&self, fract: f32, width: usize, alt_style: Option<&Style>) -> BarDisplay<'_> { // The number of clusters from progress_chars to write (rounding down). let width = width / self.char_width; @@ -654,48 +630,6 @@ impl<'a> fmt::Display for PaddedStringDisplay<'a> { } } -/// Behavior of a progress bar when it is finished -/// -/// This is invoked when a [`ProgressBar`] or [`ProgressBarIter`] completes and -/// [`ProgressBar::is_finished`] is false. -/// -/// [`ProgressBar`]: crate::ProgressBar -/// [`ProgressBarIter`]: crate::ProgressBarIter -/// [`ProgressBar::is_finished`]: crate::ProgressBar::is_finished -#[derive(Clone, Debug)] -pub enum ProgressFinish { - /// Finishes the progress bar and leaves the current message - /// - /// Same behavior as calling [`ProgressBar::finish()`](crate::ProgressBar::finish). - AndLeave, - /// Finishes the progress bar at current position and leaves the current message - /// - /// Same behavior as calling [`ProgressBar::finish_at_current_pos()`](crate::ProgressBar::finish_at_current_pos). - AtCurrentPos, - /// Finishes the progress bar and sets a message - /// - /// Same behavior as calling [`ProgressBar::finish_with_message()`](crate::ProgressBar::finish_with_message). - WithMessage(Cow<'static, str>), - /// Finishes the progress bar and completely clears it (this is the default) - /// - /// Same behavior as calling [`ProgressBar::finish_and_clear()`](crate::ProgressBar::finish_and_clear). - AndClear, - /// Finishes the progress bar and leaves the current message and progress - /// - /// Same behavior as calling [`ProgressBar::abandon()`](crate::ProgressBar::abandon). - Abandon, - /// Finishes the progress bar and sets a message, and leaves the current progress - /// - /// Same behavior as calling [`ProgressBar::abandon_with_message()`](crate::ProgressBar::abandon_with_message). - AbandonWithMessage(Cow<'static, str>), -} - -impl Default for ProgressFinish { - fn default() -> Self { - Self::AndClear - } -} - #[derive(PartialEq, Eq, Debug, Copy, Clone)] enum Alignment { Left,