diff options
author | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2020-05-06 17:38:29 +0300 |
---|---|---|
committer | Manos Pitsidianakis <el13635@mail.ntua.gr> | 2020-05-06 17:38:29 +0300 |
commit | 330134af5a9d180093828405fad26d3ffd1696a8 (patch) | |
tree | 3a7cb7f2094db63ec64884cf5c7db7257f97ebe2 /melib | |
parent | d580b2541532a075402285c636462100366ff580 (diff) |
maildir: update mailbox unread count on file rename event
Diffstat (limited to 'melib')
-rw-r--r-- | melib/src/backends/maildir.rs | 55 | ||||
-rw-r--r-- | melib/src/backends/maildir/backend.rs | 28 |
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), |