From 8a0e702127bc6229cad363918ae7542b26c11317 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Sun, 28 Jul 2019 18:52:45 +0300 Subject: [PATCH] melib,ui: add MailboxEntry enum Use an enum to describe a mailbox's state in ui::conf::Account instead of Result. --- melib/src/collection.rs | 39 +++-- melib/src/mailbox.rs | 11 +- melib/src/thread.rs | 13 +- ui/src/components/mail/compose.rs | 2 +- ui/src/components/mail/listing.rs | 10 +- ui/src/components/mail/listing/compact.rs | 30 ++-- ui/src/components/mail/listing/plain.rs | 7 +- ui/src/components/mail/listing/thread.rs | 23 +-- ui/src/components/mail/view/thread.rs | 8 +- ui/src/components/utilities.rs | 2 +- ui/src/conf/accounts.rs | 166 +++++++++++++--------- ui/src/state.rs | 9 +- 12 files changed, 176 insertions(+), 144 deletions(-) diff --git a/melib/src/collection.rs b/melib/src/collection.rs index ba2a9d52..e6fea0d4 100644 --- a/melib/src/collection.rs +++ b/melib/src/collection.rs @@ -106,13 +106,10 @@ impl Collection { } } /* envelope is not in threads, so insert it */ - let env = self.envelopes.entry(new_hash).or_default() as *mut Envelope; - unsafe { - self.threads - .entry(folder_hash) - .or_default() - .insert(&mut (*env), &self.envelopes); - } + self.threads + .entry(folder_hash) + .or_default() + .insert(&mut self.envelopes, new_hash); for (h, t) in self.threads.iter_mut() { if *h == folder_hash { continue; @@ -127,7 +124,7 @@ impl Collection { &mut self, mut envelopes: FnvHashMap, folder_hash: FolderHash, - mailbox: &mut Result, + mailbox: &mut Mailbox, sent_folder: Option, ) { self.sent_folder = sent_folder; @@ -135,9 +132,7 @@ impl Collection { if self.message_ids.contains_key(e.message_id().raw()) { /* skip duplicates until a better way to handle them is found. */ //FIXME - if let Ok(mailbox) = mailbox.as_mut() { - mailbox.remove(h); - } + mailbox.remove(h); false } else { self.message_ids.insert(e.message_id().raw().to_vec(), h); @@ -214,13 +209,10 @@ impl Collection { } } /* envelope is not in threads, so insert it */ - let env = self.envelopes.entry(new_hash).or_default() as *mut Envelope; - unsafe { - self.threads - .entry(folder_hash) - .or_default() - .insert(&mut (*env), &self.envelopes); - } + self.threads + .entry(folder_hash) + .or_default() + .insert(&mut self.envelopes, new_hash); for (h, t) in self.threads.iter_mut() { if *h == folder_hash { continue; @@ -236,10 +228,17 @@ impl Collection { self.message_ids .insert(envelope.message_id().raw().to_vec(), hash); self.envelopes.insert(hash, envelope); - self.threads + if !self + .threads .entry(folder_hash) .or_default() - .insert_reply(&mut self.envelopes, hash); + .insert_reply(&mut self.envelopes, hash) + { + self.threads + .entry(folder_hash) + .or_default() + .insert(&mut self.envelopes, hash); + } &self.envelopes[&hash] } pub fn insert_reply(&mut self, env_hash: EnvelopeHash) { diff --git a/melib/src/mailbox.rs b/melib/src/mailbox.rs index 00e10799..3846d7c1 100644 --- a/melib/src/mailbox.rs +++ b/melib/src/mailbox.rs @@ -27,7 +27,6 @@ use crate::backends::Folder; pub use crate::email::*; -use crate::error::Result; use crate::thread::ThreadHash; pub use crate::thread::{SortField, SortOrder, ThreadNode, Threads}; @@ -47,19 +46,15 @@ pub struct Mailbox { } impl Mailbox { - pub fn new( - folder: Folder, - envelopes: Result<&FnvHashMap>, - ) -> Result { - let envelopes = envelopes?; + pub fn new(folder: Folder, envelopes: &FnvHashMap) -> Mailbox { let name = folder.name().into(); let envelopes = envelopes.keys().cloned().collect(); - Ok(Mailbox { + Mailbox { folder, name, envelopes, ..Default::default() - }) + } } pub fn name(&self) -> &str { diff --git a/melib/src/thread.rs b/melib/src/thread.rs index 9b034e6c..63db8425 100644 --- a/melib/src/thread.rs +++ b/melib/src/thread.rs @@ -938,12 +938,7 @@ impl Threads { new_hash_set.difference(&self.hash_set).cloned().collect(); for h in difference { debug!("inserting {}", envelopes[&h].subject()); - let env = envelopes.entry(h).or_default() as *mut Envelope; - unsafe { - // `envelopes` is borrowed immutably and `insert` only changes the envelope's - // `thread` field. - self.insert(&mut (*env), envelopes); - } + self.insert(envelopes, h); } self.create_root_set(envelopes); @@ -953,10 +948,10 @@ impl Threads { tree.retain(|t| root_set.contains(&t.id)); } - pub fn insert(&mut self, envelope: &mut Envelope, envelopes: &Envelopes) { - self.link_envelope(envelope); + pub fn insert(&mut self, envelopes: &mut Envelopes, env_hash: EnvelopeHash) { + self.link_envelope(envelopes.get_mut(&env_hash).unwrap()); { - let id = self.message_ids[envelope.message_id().raw()]; + let id = self.message_ids[envelopes[&env_hash].message_id().raw()]; self.rebuild_thread(id, envelopes); } } diff --git a/ui/src/components/mail/compose.rs b/ui/src/components/mail/compose.rs index 573ade6d..b3db659e 100644 --- a/ui/src/components/mail/compose.rs +++ b/ui/src/components/mail/compose.rs @@ -143,7 +143,7 @@ impl Composer { context: &Context, ) -> Self { let account = &context.accounts[coordinates.0]; - let mailbox = &account[coordinates.1].as_ref().unwrap(); + let mailbox = &account[coordinates.1].unwrap(); let threads = &account.collection.threads[&mailbox.folder.hash()]; let thread_nodes = &threads.thread_nodes(); let mut ret = Composer::default(); diff --git a/ui/src/components/mail/listing.rs b/ui/src/components/mail/listing.rs index 8d44d380..fbb78c30 100644 --- a/ui/src/components/mail/listing.rs +++ b/ui/src/components/mail/listing.rs @@ -532,12 +532,16 @@ impl Listing { Ok(_) => { let account = &context.accounts[index]; let count = account[entries[&folder_idx].hash()] - .as_ref() .unwrap() .envelopes .iter() - .map(|h| &account.collection[&h]) - .filter(|e| !e.is_seen()) + .filter_map(|h| { + if account.collection[&h].is_seen() { + None + } else { + Some(()) + } + }) .count(); let len = s.len(); s.insert_str( diff --git a/ui/src/components/mail/listing/compact.rs b/ui/src/components/mail/listing/compact.rs index e3fa4023..68cb0bef 100644 --- a/ui/src/components/mail/listing/compact.rs +++ b/ui/src/components/mail/listing/compact.rs @@ -539,13 +539,14 @@ impl CompactListing { // Get mailbox as a reference. // match context.accounts[self.cursor_pos.0].status(folder_hash) { - Ok(_) => {} + Ok(()) => {} Err(_) => { + let message: String = context.accounts[self.cursor_pos.0][folder_hash].to_string(); self.data_columns.columns[0] = - CellBuffer::new("Loading.".len(), 1, Cell::with_char(' ')); + CellBuffer::new(message.len(), 1, Cell::with_char(' ')); self.length = 0; write_string_to_grid( - "Loading.", + message.as_str(), &mut self.data_columns.columns[0], Color::Default, Color::Default, @@ -562,7 +563,7 @@ impl CompactListing { } let account = &context.accounts[self.cursor_pos.0]; - let mailbox = account[self.cursor_pos.1].as_ref().unwrap(); + let mailbox = &account[self.cursor_pos.1].unwrap(); let threads = &account.collection.threads[&mailbox.folder.hash()]; self.order.clear(); @@ -778,7 +779,11 @@ impl CompactListing { return; } let account = &context.accounts[self.cursor_pos.0]; - let mailbox = account[self.cursor_pos.1].as_ref().unwrap(); + let mailbox = if account[self.cursor_pos.1].is_available() { + account[self.cursor_pos.1].unwrap() + } else { + return; + }; let threads = &account.collection.threads[&mailbox.folder.hash()]; self.length = 0; @@ -913,10 +918,7 @@ impl CompactListing { } fn get_envelope_under_cursor(&self, cursor: usize, context: &Context) -> EnvelopeHash { let account = &context.accounts[self.cursor_pos.0]; - let folder_hash = account[self.cursor_pos.1] - .as_ref() - .map(|m| m.folder.hash()) - .unwrap(); + let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash(); let threads = &account.collection.threads[&folder_hash]; if self.filtered_selection.is_empty() { let thread_node = threads.root_set(cursor); @@ -1035,10 +1037,7 @@ impl Component for CompactListing { .thread() .clone() }; - let folder_hash = account[self.cursor_pos.1] - .as_ref() - .map(|m| m.folder.hash()) - .unwrap(); + let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash(); let threads = &account.collection.threads[&folder_hash]; let root_thread_index = threads.root_iter().position(|t| t == thread_hash); if let Some(pos) = root_thread_index { @@ -1168,10 +1167,7 @@ impl Component for CompactListing { let i = self.get_envelope_under_cursor(self.cursor_pos.2, context); let account = &mut context.accounts[self.cursor_pos.0]; let thread_hash = account.get_env(&i).thread(); - let folder_hash = account[self.cursor_pos.1] - .as_ref() - .map(|m| m.folder.hash()) - .unwrap(); + let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash(); let threads = account.collection.threads.entry(folder_hash).or_default(); let thread_group = threads.thread_nodes()[&thread_hash].thread_group(); let thread_group = threads.find(thread_group); diff --git a/ui/src/components/mail/listing/plain.rs b/ui/src/components/mail/listing/plain.rs index f045ba3a..df28ac71 100644 --- a/ui/src/components/mail/listing/plain.rs +++ b/ui/src/components/mail/listing/plain.rs @@ -266,10 +266,11 @@ impl PlainListing { match context.accounts[self.cursor_pos.0].status(folder_hash) { Ok(_) => {} Err(_) => { - self.content = CellBuffer::new(MAX_COLS, 1, Cell::with_char(' ')); + let message: String = context.accounts[self.cursor_pos.0][folder_hash].to_string(); + self.content = CellBuffer::new(message.len(), 1, Cell::with_char(' ')); self.length = 0; write_string_to_grid( - "Loading.", + message.as_str(), &mut self.content, Color::Default, Color::Default, @@ -280,7 +281,7 @@ impl PlainListing { } } let account = &context.accounts[self.cursor_pos.0]; - let mailbox = &account[self.cursor_pos.1].as_ref().unwrap(); + let mailbox = &account[self.cursor_pos.1].unwrap(); self.length = mailbox.len(); self.content = CellBuffer::new(MAX_COLS, self.length + 1, Cell::with_char(' ')); diff --git a/ui/src/components/mail/listing/thread.rs b/ui/src/components/mail/listing/thread.rs index af2682c9..de9537dd 100644 --- a/ui/src/components/mail/listing/thread.rs +++ b/ui/src/components/mail/listing/thread.rs @@ -137,9 +137,11 @@ impl ListingTrait for ThreadListing { } fn highlight_line(&mut self, grid: &mut CellBuffer, area: Area, idx: usize, context: &Context) { - let mailbox = &context.accounts[self.cursor_pos.0][self.cursor_pos.1] - .as_ref() - .unwrap(); + let mailbox = if context.accounts[self.cursor_pos.0][self.cursor_pos.1].is_available() { + context.accounts[self.cursor_pos.0][self.cursor_pos.1].unwrap() + } else { + return; + }; if mailbox.is_empty() || mailbox.len() <= idx { return; } @@ -222,10 +224,11 @@ impl ThreadListing { match context.accounts[self.cursor_pos.0].status(folder_hash) { Ok(_) => {} Err(_) => { - self.content = CellBuffer::new(MAX_COLS, 1, Cell::with_char(' ')); + let message: String = context.accounts[self.cursor_pos.0][folder_hash].to_string(); + self.content = CellBuffer::new(message.len(), 1, Cell::with_char(' ')); self.length = 0; write_string_to_grid( - "Loading.", + message.as_str(), &mut self.content, Color::Default, Color::Default, @@ -236,7 +239,7 @@ impl ThreadListing { } } let account = &context.accounts[self.cursor_pos.0]; - let mailbox = account[self.cursor_pos.1].as_ref().unwrap(); + let mailbox = account[self.cursor_pos.1].unwrap(); let threads = &account.collection.threads[&mailbox.folder.hash()]; self.length = threads.len(); @@ -328,9 +331,11 @@ impl ThreadListing { } fn highlight_line_self(&mut self, idx: usize, context: &Context) { - let mailbox = &context.accounts[self.cursor_pos.0][self.cursor_pos.1] - .as_ref() - .unwrap(); + let mailbox = if context.accounts[self.cursor_pos.0][self.cursor_pos.1].is_available() { + context.accounts[self.cursor_pos.0][self.cursor_pos.1].unwrap() + } else { + return; + }; if mailbox.is_empty() { return; } diff --git a/ui/src/components/mail/view/thread.rs b/ui/src/components/mail/view/thread.rs index ed6936bb..daf22102 100644 --- a/ui/src/components/mail/view/thread.rs +++ b/ui/src/components/mail/view/thread.rs @@ -158,7 +158,7 @@ impl ThreadView { fn initiate(&mut self, expanded_hash: Option, context: &Context) { /* stack to push thread messages in order in order to pop and print them later */ let account = &context.accounts[self.coordinates.0]; - let mailbox = &account[self.coordinates.1].as_ref().unwrap(); + let mailbox = &account[self.coordinates.1].unwrap(); let threads = &account.collection.threads[&mailbox.folder.hash()]; let thread_iter = threads.thread_iter(self.coordinates.2); @@ -607,7 +607,7 @@ impl ThreadView { /* First draw the thread subject on the first row */ let y = if self.dirty { let account = &context.accounts[self.coordinates.0]; - let mailbox = &account[self.coordinates.1].as_ref().unwrap(); + let mailbox = &account[self.coordinates.1].unwrap(); let threads = &account.collection.threads[&mailbox.folder.hash()]; let thread_node = &threads.thread_nodes()[&threads.root_set(self.coordinates.2)]; let i = if let Some(i) = thread_node.message() { @@ -688,7 +688,7 @@ impl ThreadView { /* First draw the thread subject on the first row */ let y = { let account = &context.accounts[self.coordinates.0]; - let mailbox = &account[self.coordinates.1].as_ref().unwrap(); + let mailbox = &account[self.coordinates.1].unwrap(); let threads = &account.collection.threads[&mailbox.folder.hash()]; let thread_node = &threads.thread_nodes()[&threads.root_set(self.coordinates.2)]; let i = if let Some(i) = thread_node.message() { @@ -904,7 +904,7 @@ impl Component for ThreadView { UIEvent::Input(Key::Char('e')) => { { let account = &context.accounts[self.coordinates.0]; - let mailbox = &account[self.coordinates.1].as_ref().unwrap(); + let mailbox = &account[self.coordinates.1].unwrap(); let threads = &account.collection.threads[&mailbox.folder.hash()]; let thread_node = &threads.thread_nodes()[&threads.root_set(self.coordinates.2)]; diff --git a/ui/src/components/utilities.rs b/ui/src/components/utilities.rs index 4b3d4cea..72b9e710 100644 --- a/ui/src/components/utilities.rs +++ b/ui/src/components/utilities.rs @@ -921,7 +921,7 @@ impl Component for StatusBar { } } let account = &context.accounts[*idx_a]; - let m = &account[*idx_f].as_ref().unwrap(); + let m = &account[*idx_f].unwrap(); self.status = format!( "{} | Mailbox: {}, Messages: {}, New: {}", self.mode, diff --git a/ui/src/conf/accounts.rs b/ui/src/conf/accounts.rs index fe2981ba..3bf8bd8a 100644 --- a/ui/src/conf/accounts.rs +++ b/ui/src/conf/accounts.rs @@ -46,24 +46,75 @@ use std::ops::{Index, IndexMut}; use std::result; use std::sync::Arc; -pub type Worker = Option>, Result)>>; +pub type Worker = Option, Mailbox)>>>; macro_rules! mailbox { ($idx:expr, $folders:expr) => { - $folders - .get_mut(&$idx) - .unwrap() - .as_mut() - .unwrap() - .as_mut() - .unwrap() + $folders.get_mut(&$idx).unwrap().unwrap_mut() }; } +#[derive(Serialize, Debug)] +pub enum MailboxEntry { + Available(Mailbox), + Failed(MeliError), + /// first argument is done work, and second is total work + Parsing(usize, usize), + /// first argument is done work, and second is total work + Threading(usize, usize), +} + +impl std::fmt::Display for MailboxEntry { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!( + f, + "{}", + match self { + MailboxEntry::Available(ref m) => m.name().to_string(), + MailboxEntry::Failed(ref e) => e.to_string(), + MailboxEntry::Parsing(done, total) => { + format!("Parsing messages. [{}/{}]", done, total) + } + MailboxEntry::Threading(done, total) => { + format!("Calculating threads. [{}/{}]", done, total) + } + } + ) + } +} +impl MailboxEntry { + pub fn is_available(&self) -> bool { + if let MailboxEntry::Available(_) = self { + true + } else { + false + } + } + pub fn is_parsing(&self) -> bool { + if let MailboxEntry::Parsing(_, _) = self { + true + } else { + false + } + } + pub fn unwrap_mut(&mut self) -> &mut Mailbox { + match self { + MailboxEntry::Available(ref mut m) => m, + e => panic!(format!("mailbox is not available! {:#}", e)), + } + } + pub fn unwrap(&self) -> &Mailbox { + match self { + MailboxEntry::Available(ref m) => m, + e => panic!(format!("mailbox is not available! {:#}", e)), + } + } +} + #[derive(Debug)] pub struct Account { name: String, - pub(crate) folders: FnvHashMap>>, + pub(crate) folders: FnvHashMap, pub(crate) folders_order: Vec, folder_names: FnvHashMap, tree: Vec, @@ -113,31 +164,21 @@ impl Drop for Account { pub struct MailboxIterator<'a> { folders_order: &'a [FolderHash], - folders: &'a FnvHashMap>>, + folders: &'a FnvHashMap, pos: usize, } impl<'a> Iterator for MailboxIterator<'a> { - type Item = Option<&'a Mailbox>; + type Item = &'a MailboxEntry; - fn next(&mut self) -> Option> { + fn next(&mut self) -> Option<&'a MailboxEntry> { if self.pos == self.folders.len() { return None; } let fh = &self.folders_order[self.pos]; - if self.pos == self.folders.len() { - return None; - } - self.pos += 1; - if self.folders[&fh].is_none() { - return Some(None); - } - if let Some(Err(_)) = self.folders[&fh] { - return Some(None); - } - Some(Some(self.folders[&fh].as_ref().unwrap().as_ref().unwrap())) + Some(&self.folders[&fh]) } } @@ -156,7 +197,7 @@ impl Account { ) -> Self { let mut backend = map.get(settings.account().format())(settings.account()); let mut ref_folders: FnvHashMap = backend.folders(); - let mut folders: FnvHashMap>> = + let mut folders: FnvHashMap = FnvHashMap::with_capacity_and_hasher(ref_folders.len(), Default::default()); let mut folders_order: Vec = Vec::with_capacity(ref_folders.len()); let mut workers: FnvHashMap = FnvHashMap::default(); @@ -208,7 +249,7 @@ impl Account { } } } - folders.insert(*h, None); + folders.insert(*h, MailboxEntry::Parsing(0, 0)); workers.insert( *h, Account::new_worker(f.clone(), &mut backend, notify_fn.clone()), @@ -282,15 +323,19 @@ impl Account { .collect::>() }); let hash = folder.hash(); - let m = Mailbox::new(folder, envelopes.as_ref().map_err(Clone::clone)); - tx.send(AsyncStatus::Payload((envelopes, m))); + if envelopes.is_err() { + tx.send(AsyncStatus::Payload(Err(envelopes.unwrap_err()))); + notify_fn.notify(hash); + return; + } + let envelopes = envelopes.unwrap(); + let m = Mailbox::new(folder, &envelopes); + tx.send(AsyncStatus::Payload(Ok((envelopes, m)))); notify_fn.notify(hash); }))) } pub fn reload(&mut self, event: RefreshEvent, folder_hash: FolderHash) -> Option { - if self.folders[&folder_hash].is_none() - || self.folders[&folder_hash].as_ref().unwrap().is_err() - { + if !self.folders[&folder_hash].is_available() { self.event_queue.push_back((folder_hash, event)); return None; } @@ -306,15 +351,13 @@ impl Account { } RefreshEventKind::Rename(old_hash, new_hash) => { debug!("rename {} to {}", old_hash, new_hash); - let mailbox = mailbox!(&folder_hash, self.folders); - mailbox.rename(old_hash, new_hash); + mailbox!(&folder_hash, self.folders).rename(old_hash, new_hash); self.collection.rename(old_hash, new_hash, folder_hash); return Some(EnvelopeRename(old_hash, new_hash)); } RefreshEventKind::Create(envelope) => { let env_hash = envelope.hash(); - let mailbox = mailbox!(&folder_hash, self.folders); - mailbox.insert(env_hash); + mailbox!(&folder_hash, self.folders).insert(env_hash); self.collection.insert(*envelope, folder_hash); if self .sent_folder @@ -367,7 +410,7 @@ impl Account { pub fn watch(&self, r: RefreshEventConsumer) { self.backend.watch(r).unwrap(); } - /* This doesn't represent the number of correctly parsed mailboxes though */ + pub fn len(&self) -> usize { self.folders.len() } @@ -417,17 +460,18 @@ impl Account { fn load_mailbox( &mut self, folder_hash: FolderHash, - mailbox: (Result>, Result), + payload: (Result<(FnvHashMap, Mailbox)>), ) { - let (envs, mut mailbox) = mailbox; - if envs.is_err() { - self.folders.insert(folder_hash, None); + if payload.is_err() { + self.folders + .insert(folder_hash, MailboxEntry::Failed(payload.unwrap_err())); return; } - let envs = envs.unwrap(); + let (envelopes, mut mailbox) = payload.unwrap(); self.collection - .merge(envs, folder_hash, &mut mailbox, self.sent_folder); - self.folders.insert(folder_hash, Some(mailbox)); + .merge(envelopes, folder_hash, &mut mailbox, self.sent_folder); + self.folders + .insert(folder_hash, MailboxEntry::Available(mailbox)); } pub fn status(&mut self, folder_hash: FolderHash) -> result::Result<(), usize> { @@ -435,12 +479,17 @@ impl Account { None => { return Ok(()); } - Some(ref mut w) if self.folders[&folder_hash].is_none() => match w.poll() { + Some(ref mut w) if self.folders[&folder_hash].is_parsing() => match w.poll() { Ok(AsyncStatus::NoUpdate) => { return Err(0); } Ok(AsyncStatus::Finished) => {} Ok(AsyncStatus::ProgressReport(n)) => { + self.folders.entry(folder_hash).and_modify(|f| { + if let MailboxEntry::Parsing(ref mut d, _) = f { + *d += n; + } + }); return Err(n); } _ => { @@ -496,7 +545,7 @@ impl Account { } pub fn operation(&self, h: EnvelopeHash) -> Box { for mailbox in self.folders.values() { - if let Some(Ok(m)) = mailbox { + if let MailboxEntry::Available(ref m) = mailbox { if m.envelopes.contains(&h) { let operation = self.backend.operation(h, m.folder.hash()); if self.settings.account.read_only() { @@ -542,41 +591,28 @@ impl Account { } impl Index for Account { - type Output = Result; - fn index(&self, index: FolderHash) -> &Result { + type Output = MailboxEntry; + fn index(&self, index: FolderHash) -> &MailboxEntry { &self.folders[&index] - .as_ref() - .expect("BUG: Requested mailbox that is not yet available.") } } -/// Will panic if mailbox hasn't loaded, ask `status()` first. impl IndexMut for Account { - fn index_mut(&mut self, index: FolderHash) -> &mut Result { - self.folders - .get_mut(&index) - .unwrap() - .as_mut() - .expect("BUG: Requested mailbox that is not yet available.") + fn index_mut(&mut self, index: FolderHash) -> &mut MailboxEntry { + self.folders.get_mut(&index).unwrap() } } impl Index for Account { - type Output = Result; - fn index(&self, index: usize) -> &Result { + type Output = MailboxEntry; + fn index(&self, index: usize) -> &MailboxEntry { &self.folders[&self.folders_order[index]] - .as_ref() - .expect("BUG: Requested mailbox that is not yet available.") } } /// Will panic if mailbox hasn't loaded, ask `status()` first. impl IndexMut for Account { - fn index_mut(&mut self, index: usize) -> &mut Result { - self.folders - .get_mut(&self.folders_order[index]) - .unwrap() - .as_mut() - .expect("BUG: Requested mailbox that is not yet available.") + fn index_mut(&mut self, index: usize) -> &mut MailboxEntry { + self.folders.get_mut(&self.folders_order[index]).unwrap() } } diff --git a/ui/src/state.rs b/ui/src/state.rs index a2c7602c..69b8b0f3 100644 --- a/ui/src/state.rs +++ b/ui/src/state.rs @@ -276,11 +276,12 @@ impl State { return; } if let Some(notification) = self.context.accounts[idxa].reload(event, hash) { + if let UIEvent::Notification(_, _) = notification { + self.context + .replies + .push_back(UIEvent::MailboxUpdate((idxa, hash))); + } self.rcv_event(notification); - } else { - self.context - .replies - .push_back(UIEvent::MailboxUpdate((idxa, hash))); } } else { debug!(