summaryrefslogtreecommitdiffstats
path: root/melib
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2020-05-06 17:38:29 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2020-05-06 17:38:29 +0300
commit330134af5a9d180093828405fad26d3ffd1696a8 (patch)
tree3a7cb7f2094db63ec64884cf5c7db7257f97ebe2 /melib
parentd580b2541532a075402285c636462100366ff580 (diff)
maildir: update mailbox unread count on file rename event
Diffstat (limited to 'melib')
-rw-r--r--melib/src/backends/maildir.rs55
-rw-r--r--melib/src/backends/maildir/backend.rs28
2 files changed, 56 insertions, 27 deletions
diff --git a/melib/src/backends/maildir.rs b/melib/src/backends/maildir.rs
index 4d679a95..28e2af66 100644
--- a/melib/src/backends/maildir.rs
+++ b/melib/src/backends/maildir.rs
@@ -96,30 +96,10 @@ impl<'a> BackendOp for MaildirOp {
/* Unwrap is safe since we use ? above. */
Ok(unsafe { self.slice.as_ref().unwrap().as_slice() })
}
+
fn fetch_flags(&self) -> Flag {
- let mut flag = Flag::default();
let path = self.path();
- let path = path.to_str().unwrap(); // Assume UTF-8 validity
- if !path.contains(":2,") {
- return flag;
- }
-
- for f in path.chars().rev() {
- match f {
- ',' => break,
- 'D' => flag |= Flag::DRAFT,
- 'F' => flag |= Flag::FLAGGED,
- 'P' => flag |= Flag::PASSED,
- 'R' => flag |= Flag::REPLIED,
- 'S' => flag |= Flag::SEEN,
- 'T' => flag |= Flag::TRASHED,
- _ => {
- debug!("DEBUG: in fetch_flags, path is {}", path);
- }
- }
- }
-
- flag
+ path.flags()
}
fn set_flag(&mut self, envelope: &mut Envelope, f: Flag, value: bool) -> Result<()> {
@@ -313,3 +293,34 @@ impl BackendMailbox for MaildirMailbox {
Ok((*self.unseen.lock()?, *self.total.lock()?))
}
}
+
+pub trait MaildirPathTrait {
+ fn flags(&self) -> Flag;
+}
+
+impl MaildirPathTrait for Path {
+ fn flags(&self) -> Flag {
+ let mut flag = Flag::default();
+ let path = self.to_string_lossy();
+ if !path.contains(":2,") {
+ return flag;
+ }
+
+ for f in path.chars().rev() {
+ match f {
+ ',' => break,
+ 'D' => flag |= Flag::DRAFT,
+ 'F' => flag |= Flag::FLAGGED,
+ 'P' => flag |= Flag::PASSED,
+ 'R' => flag |= Flag::REPLIED,
+ 'S' => flag |= Flag::SEEN,
+ 'T' => flag |= Flag::TRASHED,
+ _ => {
+ debug!("DEBUG: in MaildirPathTrait::flags(), encountered unknown flag marker {:?}, path is {}", f, path);
+ }
+ }
+ }
+
+ flag
+ }
+}
diff --git a/melib/src/backends/maildir/backend.rs b/melib/src/backends/maildir/backend.rs
index 1072b72b..210669bf 100644
--- a/melib/src/backends/maildir/backend.rs
+++ b/melib/src/backends/maildir/backend.rs
@@ -20,7 +20,7 @@
*/
use super::{
- BackendMailbox, BackendOp, MailBackend, Mailbox, MailboxHash, RefreshEvent,
+ BackendMailbox, BackendOp, MailBackend, Mailbox, MailboxHash, MaildirPathTrait, RefreshEvent,
RefreshEventConsumer, RefreshEventKind::*,
};
use super::{MaildirMailbox, MaildirOp};
@@ -485,15 +485,20 @@ impl MailBackend for MaildirType {
&index_lock[&hash].buf.display()
),
}
+ index_lock.entry(hash).and_modify(|e| {
+ e.removed = false;
+ });
continue;
}
+ *mailbox_counts[&mailbox_hash].1.lock().unwrap() -= 1;
+ if !pathbuf.flags().contains(Flag::SEEN) {
+ *mailbox_counts[&mailbox_hash].0.lock().unwrap() -= 1;
+ }
index_lock.entry(hash).and_modify(|e| {
e.removed = true;
});
- //FIXME: check if envelope was unseen to update unseen count
- *mailbox_counts[&mailbox_hash].1.lock().unwrap() += 1;
sender.send(RefreshEvent {
hash: mailbox_hash,
kind: Remove(hash),
@@ -511,6 +516,10 @@ impl MailBackend for MaildirType {
let mut hash_indexes_lock = hash_indexes.lock().unwrap();
let index_lock = hash_indexes_lock.entry(mailbox_hash).or_default();
+ // TODO: Represent index states with an enum: make illegal
+ // states unrepresentable.
+ let was_seen: bool = src.flags().contains(Flag::SEEN);
+ let is_seen: bool = dest.flags().contains(Flag::SEEN);
if index_lock.contains_key(&old_hash)
&& !index_lock[&old_hash].removed
@@ -524,11 +533,17 @@ impl MailBackend for MaildirType {
hash: get_path_hash!(dest),
kind: Rename(old_hash, new_hash),
});
+ if !was_seen && is_seen {
+ let mut lck = mailbox_counts[&mailbox_hash].0.lock().unwrap();
+ *lck = lck.saturating_sub(1);
+ } else if was_seen && !is_seen {
+ *mailbox_counts[&mailbox_hash].0.lock().unwrap() += 1;
+ }
mailbox_index.lock().unwrap().insert(new_hash,get_path_hash!(dest) );
index_lock.insert(new_hash, dest.into());
continue;
} else if !index_lock.contains_key(&new_hash)
- || index_lock
+ && index_lock
.get(&old_hash)
.map(|e| e.removed)
.unwrap_or(false)
@@ -571,7 +586,7 @@ impl MailBackend for MaildirType {
if !env.is_seen() {
*mailbox_counts[&mailbox_hash].0.lock().unwrap() += 1;
}
- *mailbox_counts[&mailbox_hash].1.lock().unwrap() += 1;
+ *mailbox_counts[&mailbox_hash].1.lock().unwrap() += 1;
sender.send(RefreshEvent {
hash: mailbox_hash,
kind: Create(Box::new(env)),
@@ -581,6 +596,9 @@ impl MailBackend for MaildirType {
debug!("not valid email");
}
} else {
+ if was_seen && !is_seen {
+ *mailbox_counts[&mailbox_hash].0.lock().unwrap() += 1;
+ }
sender.send(RefreshEvent {
hash: get_path_hash!(dest),
kind: Rename(old_hash, new_hash),