summaryrefslogtreecommitdiff
path: root/src/policy.rs
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2021-01-05 12:54:53 +0200
committerLars Wirzenius <liw@liw.fi>2021-01-05 14:05:37 +0200
commit8a42fc1c9dc3da6936fe8e1d0d16fbe8a60ec520 (patch)
tree7c2d38852e6f1eec5c357b2304a04dc332b8d953 /src/policy.rs
parent678e65c57ae983ef66d16e92965814b0f3f0d73f (diff)
downloadobnam2-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.rs64
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
+}