melib: make MailBackend::folders return Result

Change folders() signature:
-    fn folders(&self) -> FnvHashMap<FolderHash, Folder>;
+    fn folders(&self) -> Result<FnvHashMap<FolderHash, Folder>>;

Imap may not be online, therefore we need the ability to return an
error.
jmap
Manos Pitsidianakis 2019-11-23 17:47:24 +02:00
parent 3d3ead02e9
commit 41a678c6ef
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
7 changed files with 30 additions and 28 deletions

View File

@ -201,7 +201,7 @@ pub trait MailBackend: ::std::fmt::Debug + Send + Sync {
sender: RefreshEventConsumer,
work_context: WorkContext,
) -> Result<std::thread::ThreadId>;
fn folders(&self) -> FnvHashMap<FolderHash, Folder>;
fn folders(&self) -> Result<FnvHashMap<FolderHash, Folder>>;
fn operation(&self, hash: EnvelopeHash) -> Box<dyn BackendOp>;
fn save(&self, bytes: &[u8], folder: &str, flags: Option<Flag>) -> Result<()>;

View File

@ -269,17 +269,17 @@ impl MailBackend for ImapType {
Ok(handle.thread().id())
}
fn folders(&self) -> FnvHashMap<FolderHash, Folder> {
fn folders(&self) -> Result<FnvHashMap<FolderHash, Folder>> {
{
let folders = self.folders.read().unwrap();
if !folders.is_empty() {
return folders
return Ok(folders
.iter()
.map(|(h, f)| (*h, Box::new(Clone::clone(f)) as Folder))
.collect();
.collect());
}
}
let mut folders = self.folders.write().unwrap();
let mut folders = self.folders.write()?;
*folders = ImapType::imap_folders(&self.connection);
folders.retain(|_, f| (self.is_subscribed)(f.path()));
let keys = folders.keys().cloned().collect::<FnvHashSet<FolderHash>>();
@ -287,10 +287,10 @@ impl MailBackend for ImapType {
f.children.retain(|c| keys.contains(c));
}
*self.online.lock().unwrap() = true;
folders
Ok(folders
.iter()
.map(|(h, f)| (*h, Box::new(Clone::clone(f)) as Folder))
.collect()
.collect())
}
fn operation(&self, hash: EnvelopeHash) -> Box<dyn BackendOp> {

View File

@ -186,12 +186,15 @@ impl MailBackend for MaildirType {
fn is_online(&self) -> bool {
true
}
fn folders(&self) -> FnvHashMap<FolderHash, Folder> {
self.folders
fn folders(&self) -> Result<FnvHashMap<FolderHash, Folder>> {
Ok(self
.folders
.iter()
.map(|(h, f)| (*h, f.clone() as Folder))
.collect()
.collect())
}
fn get(&mut self, folder: &Folder) -> Async<Result<Vec<Envelope>>> {
self.multicore(4, folder)
}

View File

@ -536,13 +536,14 @@ impl MailBackend for MboxType {
})?;
Ok(handle.thread().id())
}
fn folders(&self) -> FnvHashMap<FolderHash, Folder> {
self.folders
fn folders(&self) -> Result<FnvHashMap<FolderHash, Folder>> {
Ok(self
.folders
.lock()
.unwrap()
.iter()
.map(|(h, f)| (*h, f.clone() as Folder))
.collect()
.collect())
}
fn operation(&self, hash: EnvelopeHash) -> Box<dyn BackendOp> {
let (offset, length) = {

View File

@ -268,13 +268,13 @@ impl MailBackend for NotmuchDb {
.spawn(move || {})?;
Ok(handle.thread().id())
}
fn folders(&self) -> FnvHashMap<FolderHash, Folder> {
self.folders
fn folders(&self) -> Result<FnvHashMap<FolderHash, Folder>> {
Ok(self.folders
.read()
.unwrap()
.iter()
.map(|(k, f)| (*k, BackendFolder::clone(f)))
.collect()
.collect())
}
fn operation(&self, hash: EnvelopeHash) -> Box<dyn BackendOp> {
Box::new(NotmuchOp {

View File

@ -289,8 +289,8 @@ impl Account {
}
fn init(&mut self) {
let mut ref_folders: FnvHashMap<FolderHash, Folder> =
self.backend.read().unwrap().folders();
let ref_folders: FnvHashMap<FolderHash, Folder> =
self.backend.read().unwrap().folders().unwrap();
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());
@ -575,7 +575,7 @@ impl Account {
}
let ref_folders: FnvHashMap<FolderHash, Folder> =
self.backend.read().unwrap().folders();
self.backend.read().unwrap().folders().unwrap();
let folder_conf = &self.settings.folder_confs[&self.folder_names[&folder_hash]];
if folder_conf.folder_conf().ignore.is_true() {
return Some(UIEvent::MailboxUpdate((self.index, folder_hash)));
@ -626,7 +626,7 @@ impl Account {
}
RefreshEventKind::Rescan => {
let ref_folders: FnvHashMap<FolderHash, Folder> =
self.backend.read().unwrap().folders();
self.backend.read().unwrap().folders().unwrap();
let handle = Account::new_worker(
&self.settings,
ref_folders[&folder_hash].clone(),
@ -686,8 +686,12 @@ impl Account {
self.folders.is_empty()
}
pub fn list_folders(&self) -> Vec<Folder> {
let mut folders = self.backend.read().unwrap().folders();
let folder_confs = self.settings.conf().folders();
let mut folders = if let Ok(folders) = self.backend.read().unwrap().folders() {
folders
} else {
return Vec::new();
};
//debug!("folder renames: {:?}", folder_renames);
for f in folders.values_mut() {
if let Some(r) = folder_confs.get(f.path()) {

View File

@ -147,13 +147,7 @@ impl Context {
let was_online = accounts[account_pos].is_online;
if accounts[account_pos].is_online() {
if !was_online {
for folder in accounts[account_pos]
.backend
.read()
.unwrap()
.folders()
.values()
{
for folder in accounts[account_pos].list_folders() {
debug!("hash & folder: {:?} {}", folder.hash(), folder.name());
mailbox_hashes.insert(folder.hash(), account_pos);
}