summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2019-07-28 18:52:45 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2019-07-28 20:15:41 +0300
commit8a0e702127bc6229cad363918ae7542b26c11317 (patch)
tree20dd37642c21e2d634c512496c33b2ca5761dce9
parent5b679be782e4930be393654c1a3095422bcf242e (diff)
melib,ui: add MailboxEntry enum
Use an enum to describe a mailbox's state in ui::conf::Account instead of Result.
-rw-r--r--melib/src/collection.rs39
-rw-r--r--melib/src/mailbox.rs11
-rw-r--r--melib/src/thread.rs13
-rw-r--r--ui/src/components/mail/compose.rs2
-rw-r--r--ui/src/components/mail/listing.rs10
-rw-r--r--ui/src/components/mail/listing/compact.rs30
-rw-r--r--ui/src/components/mail/listing/plain.rs7
-rw-r--r--ui/src/components/mail/listing/thread.rs23
-rw-r--r--ui/src/components/mail/view/thread.rs8
-rw-r--r--ui/src/components/utilities.rs2
-rw-r--r--ui/src/conf/accounts.rs166
-rw-r--r--ui/src/state.rs9
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<EnvelopeHash, Envelope>,
folder_hash: FolderHash,
- mailbox: &mut Result<Mailbox>,
+ mailbox: &mut Mailbox,
sent_folder: Option<FolderHash>,
) {
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<EnvelopeHash, Envelope>>,
- ) -> Result<Mailbox> {
- let envelopes = envelopes?;
+ pub fn new(folder: Folder, envelopes: &FnvHashMap<EnvelopeHash, Envelope>) -> 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<ThreadHash>, 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<Async<(Result<FnvHashMap<EnvelopeHash, Envelope>>, Result<Mailbox>)>>;
+pub type Worker = Option<Async<Result<(FnvHashMap<EnvelopeHash, Envelope>, 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<FolderHash, Option<Result<Mailbox>>>,
+ pub(crate) folders: FnvHashMap<FolderHash, MailboxEntry>,
pub(crate) folders_order: Vec<FolderHash>,
folder_names: FnvHashMap<FolderHash, String>,
tree: Vec<FolderNode>,
@@ -113,31 +164,21 @@ impl Drop for Account {
pub struct MailboxIterator<'a> {
folders_order: &'a [FolderHash],
- folders: &'a FnvHashMap<FolderHash, Option<Result<Mailbox>>>,
+ folders: &'a FnvHashMap<FolderHash, MailboxEntry>,
pos: usize,
}
impl<'a> Iterator for MailboxIterator<'a> {
- type Item = Option<&'a Mailbox>;
+ type Item = &'a MailboxEntry;
- fn next(&mut self) -> Option<Option<&'a Mailbox>> {
+ 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<FolderHash, Folder> = backend.folders();
- let mut folders: FnvHashMap<FolderHash, Option<Result<Mailbox>>> =
+ let mut folders: FnvHashMap<FolderHash, MailboxEntry> =
FnvHashMap::with_capacity_and_hasher(ref_folders.len(), Default::default());
let mut folders_order: Vec<FolderHash> = Vec::with_capacity(ref_folders.len());
let mut workers: FnvHashMap<FolderHash, Worker> = 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::<FnvHashMap<EnvelopeHash, Envelope>>()
});
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<UIEvent> {
- 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<FnvHashMap<EnvelopeHash, Envelope>>, Result<Mailbox>),
+ payload: (Result<(FnvHashMap<EnvelopeHash, Envelope>, 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<BackendOp> {
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<FolderHash> for Account {
- type Output = Result<Mailbox>;
- fn index(&self, index: FolderHash) -> &Result<Mailbox> {
+ 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<FolderHash> for Account {
- fn index_mut(&mut self, index: FolderHash) -> &mut Result<Mailbox> {
- 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<usize> for Account {
- type Output = Result<Mailbox>;
- fn index(&self, index: usize) -> &Result<Mailbox> {
+ 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<usize> for Account {
- fn index_mut(&mut self, index: usize) -> &mut Result<Mailbox> {
- 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!(