diff options
author | Lars Wirzenius <liw@liw.fi> | 2021-01-05 12:54:53 +0200 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2021-01-05 14:05:37 +0200 |
commit | 8a42fc1c9dc3da6936fe8e1d0d16fbe8a60ec520 (patch) | |
tree | 7c2d38852e6f1eec5c357b2304a04dc332b8d953 /src/policy.rs | |
parent | 678e65c57ae983ef66d16e92965814b0f3f0d73f (diff) | |
download | obnam2-8a42fc1c9dc3da6936fe8e1d0d16fbe8a60ec520.tar.gz |
refactor: move policy on whether to back up a file into a module
This commit also splits up the src/cmd/backup.rs module into other,
smaller, more cohesive modules that are easier to understand and use.
Diffstat (limited to 'src/policy.rs')
-rw-r--r-- | src/policy.rs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/policy.rs b/src/policy.rs new file mode 100644 index 0000000..032b851 --- /dev/null +++ b/src/policy.rs @@ -0,0 +1,64 @@ +use crate::backup_reason::Reason; +use crate::fsentry::FilesystemEntry; +use crate::generation::LocalGeneration; +use log::{debug, warn}; + +pub struct BackupPolicy { + new: bool, + old_if_changed: bool, +} + +impl BackupPolicy { + pub fn new() -> Self { + Self { + new: true, + old_if_changed: true, + } + } + + pub fn needs_backup(&self, old: &LocalGeneration, new_entry: &FilesystemEntry) -> Reason { + let new_name = new_entry.pathbuf(); + let reason = match old.get_file(&new_name) { + Ok(None) => { + if self.new { + Reason::IsNew + } else { + Reason::Skipped + } + } + Ok(Some(old_entry)) => { + if self.old_if_changed { + if file_has_changed(&old_entry, new_entry) { + Reason::Changed + } else { + Reason::Unchanged + } + } else { + Reason::Skipped + } + } + Err(err) => { + warn!( + "needs_backup: lookup in old generation returned error, ignored: {:?}: {}", + new_name, err + ); + Reason::Error + } + }; + debug!( + "needs_backup: file {:?}: policy decision: {}", + new_name, reason + ); + reason + } +} + +fn file_has_changed(old: &FilesystemEntry, new: &FilesystemEntry) -> bool { + let unchanged = old.kind() == new.kind() + && old.len() == new.len() + && old.mode() == new.mode() + && old.mtime() == new.mtime() + && old.mtime_ns() == new.mtime_ns() + && old.symlink_target() == new.symlink_target(); + !unchanged +} |