summaryrefslogtreecommitdiffstats
path: root/melib
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2019-08-01 12:04:38 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2019-08-02 01:00:37 +0300
commitac041950078310e325e5a22e50a73f647b84c972 (patch)
tree6e69170ed97dab13be002d9e713a21b3b394251f /melib
parentc87ed5012d98fcd2ebbd202bcf7b805f4037c8cc (diff)
maildir: mark removed paths
Remove events almost always come immediately before Rename events, showing that the previous name of a file is removed and then renamed. Keep proper tabs by marking removed paths instead of actually removing them.
Diffstat (limited to 'melib')
-rw-r--r--melib/src/backends/maildir.rs11
-rw-r--r--melib/src/backends/maildir/backend.rs41
2 files changed, 39 insertions, 13 deletions
diff --git a/melib/src/backends/maildir.rs b/melib/src/backends/maildir.rs
index 9dd3c8cc..be6de086 100644
--- a/melib/src/backends/maildir.rs
+++ b/melib/src/backends/maildir.rs
@@ -73,10 +73,13 @@ impl MaildirOp {
debug!("{:#?}", e);
}
}
- if let Some(path) = &map[&self.hash].modified {
- path.clone()
+ if let Some(modif) = &map[&self.hash].modified {
+ match modif {
+ PathMod::Path(ref path) => path.clone(),
+ PathMod::Hash(hash) => map[&hash].to_path_buf(),
+ }
} else {
- map.get(&self.hash).unwrap().buf.to_path_buf()
+ map.get(&self.hash).unwrap().to_path_buf()
}
}
}
@@ -161,7 +164,7 @@ impl<'a> BackendOp for MaildirOp {
let hash_index = self.hash_index.clone();
let mut map = hash_index.lock().unwrap();
let map = map.entry(self.folder_hash).or_default();
- map.entry(old_hash).or_default().modified = Some(new_name.clone());
+ map.entry(old_hash).or_default().modified = Some(PathMod::Path(new_name.clone()));
debug!("renaming {:?} to {:?}", path, new_name);
fs::rename(&path, &new_name)?;
diff --git a/melib/src/backends/maildir/backend.rs b/melib/src/backends/maildir/backend.rs
index 41d81874..2c5c053c 100644
--- a/melib/src/backends/maildir/backend.rs
+++ b/melib/src/backends/maildir/backend.rs
@@ -49,21 +49,30 @@ use std::result;
use std::sync::{Arc, Mutex};
use std::thread;
+#[derive(Clone, Debug, PartialEq)]
+pub(super) enum PathMod {
+ Path(PathBuf),
+ Hash(EnvelopeHash),
+}
+
#[derive(Debug, Default)]
pub struct MaildirPath {
pub(super) buf: PathBuf,
- pub(super) modified: Option<PathBuf>,
+ pub(super) modified: Option<PathMod>,
+ pub(super) removed: bool,
}
impl Deref for MaildirPath {
type Target = PathBuf;
fn deref(&self) -> &PathBuf {
+ assert!(!(self.removed && self.modified.is_none()));
&self.buf
}
}
impl DerefMut for MaildirPath {
fn deref_mut(&mut self) -> &mut PathBuf {
+ assert!(!(self.removed && self.modified.is_none()));
&mut self.buf
}
}
@@ -73,6 +82,7 @@ impl From<PathBuf> for MaildirPath {
MaildirPath {
buf: val,
modified: None,
+ removed: false,
}
}
}
@@ -321,16 +331,25 @@ impl MailBackend for MaildirType {
debug!("removed but not contained in index");
continue;
};
- if let Some(path) = &index_lock[&hash].modified {
- debug!(
- "envelope {} has modified path set {}",
- hash,
- path.display()
- );
+ if let Some(ref modif) = &index_lock[&hash].modified {
+ match modif {
+ PathMod::Path(path) => debug!(
+ "envelope {} has modified path set {}",
+ hash,
+ path.display()
+ ),
+ PathMod::Hash(hash) => debug!(
+ "envelope {} has modified path set {}",
+ hash,
+ &index_lock[&hash].buf.display()
+ ),
+ }
continue;
}
- index_lock.remove(&hash);
+ index_lock.entry(hash).and_modify(|e| {
+ e.removed = true;
+ });
sender.send(RefreshEvent {
hash: folder_hash,
@@ -356,7 +375,11 @@ impl MailBackend for MaildirType {
hash: get_path_hash!(dest),
kind: Rename(old_hash, new_hash),
});
- index_lock.remove(&old_hash);
+ index_lock.entry(old_hash).and_modify(|e| {
+ debug!(&e.modified);
+ e.modified = Some(PathMod::Hash(new_hash));
+ e.removed = false;
+ });
index_lock.insert(new_hash, dest.into());
continue;
} else if !index_lock.contains_key(&new_hash) {