diff options
Diffstat (limited to 'src/backup_progress.rs')
-rw-r--r-- | src/backup_progress.rs | 105 |
1 files changed, 97 insertions, 8 deletions
diff --git a/src/backup_progress.rs b/src/backup_progress.rs index 6c1d3e6..e3995f0 100644 --- a/src/backup_progress.rs +++ b/src/backup_progress.rs @@ -1,44 +1,133 @@ +//! Progress bars for Obnam. + +use crate::generation::GenId; use indicatif::{ProgressBar, ProgressStyle}; -use std::path::Path; +use std::{path::Path, time::Duration}; + +const SHOW_PROGRESS: bool = true; +/// A progress bar abstraction specific to backups. +/// +/// The progress bar is different for initial and incremental backups, +/// and for different phases of making a backup. pub struct BackupProgress { progress: ProgressBar, } impl BackupProgress { - pub fn new() -> Self { - let progress = if true { + /// Create a progress bar for an initial backup. + pub fn initial() -> Self { + let progress = if SHOW_PROGRESS { ProgressBar::new(0) } else { ProgressBar::hidden() }; - let parts = vec![ + let parts = [ + "initial backup", + "elapsed: {elapsed}", + "files: {pos}", + "current: {wide_msg}", + "{spinner}", + ]; + progress.set_style( + ProgressStyle::default_bar() + .template(&parts.join("\n")) + .expect("create indicatif ProgressStyle value"), + ); + progress.enable_steady_tick(Duration::from_millis(100)); + + Self { progress } + } + + /// Create a progress bar for an incremental backup. + pub fn incremental() -> Self { + let progress = if SHOW_PROGRESS { + ProgressBar::new(0) + } else { + ProgressBar::hidden() + }; + let parts = [ + "incremental backup", "{wide_bar}", "elapsed: {elapsed}", "files: {pos}/{len}", "current: {wide_msg}", "{spinner}", ]; - progress.set_style(ProgressStyle::default_bar().template(&parts.join("\n"))); - progress.enable_steady_tick(100); + progress.set_style( + ProgressStyle::default_bar() + .template(&parts.join("\n")) + .expect("create indicatif ProgressStyle value"), + ); + progress.enable_steady_tick(Duration::from_millis(100)); + + Self { progress } + } + + /// Create a progress bar for uploading a new generation's metadata. + pub fn upload_generation() -> Self { + let progress = ProgressBar::new(0); + let parts = [ + "uploading new generation metadata", + "elapsed: {elapsed}", + "{spinner}", + ]; + progress.set_style( + ProgressStyle::default_bar() + .template(&parts.join("\n")) + .expect("create indicatif ProgressStyle value"), + ); + progress.enable_steady_tick(Duration::from_millis(100)); + + Self { progress } + } + + /// Create a progress bar for downloading an existing generation's + /// metadata. + pub fn download_generation(gen_id: &GenId) -> Self { + let progress = ProgressBar::new(0); + let parts = ["{msg}", "elapsed: {elapsed}", "{spinner}"]; + progress.set_style( + ProgressStyle::default_bar() + .template(&parts.join("\n")) + .expect("create indicatif ProgressStyle value"), + ); + progress.enable_steady_tick(Duration::from_millis(100)); + progress.set_message(format!( + "downloading previous generation metadata: {}", + gen_id + )); Self { progress } } + /// Set the number of files that were in the previous generation. + /// + /// The new generation usually has about the same number of files, + /// so the progress bar can show progress for incremental backups + /// without having to count all the files that actually exist first. pub fn files_in_previous_generation(&self, count: u64) { self.progress.set_length(count); } + /// Update progress bar about number of problems found during a backup. pub fn found_problem(&self) { self.progress.inc(1); } + /// Update progress bar about number of actual files found. pub fn found_live_file(&self, filename: &Path) { self.progress.inc(1); - self.progress - .set_message(&format!("{}", filename.display())); + if self.progress.length() < Some(self.progress.position()) { + self.progress.set_length(self.progress.position()); + } + self.progress.set_message(format!("{}", filename.display())); } + /// Tell progress bar it's finished. + /// + /// This will remove all traces of the progress bar from the + /// screen. pub fn finish(&self) { self.progress.set_length(self.progress.position()); self.progress.finish_and_clear(); |