summaryrefslogtreecommitdiff
path: root/src/backup_progress.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/backup_progress.rs')
-rw-r--r--src/backup_progress.rs105
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();