Browse Source

melib: {create,delete}_folder returns updated folders

Potential parent folders will have their children fields updated, so
just return all folders.
async
Manos Pitsidianakis 2 years ago
parent
commit
f38d03e43a
Signed by: epilys GPG Key ID: 73627C2F690DF710
  1. 10
      melib/src/backends.rs
  2. 24
      melib/src/backends/imap.rs
  3. 18
      melib/src/backends/maildir/backend.rs
  4. 12
      melib/src/collection.rs
  5. 74
      src/conf/accounts.rs
  6. 5
      src/plugins/backend.rs

10
melib/src/backends.rs

@ -272,11 +272,17 @@ pub trait MailBackend: ::std::fmt::Debug + Send + Sync {
unimplemented!()
}
fn create_folder(&mut self, _path: String) -> Result<Folder> {
fn create_folder(
&mut self,
_path: String,
) -> Result<(FolderHash, FnvHashMap<FolderHash, Folder>)> {
Err(MeliError::new("Unimplemented."))
}
fn delete_folder(&mut self, _folder_hash: FolderHash) -> Result<()> {
fn delete_folder(
&mut self,
_folder_hash: FolderHash,
) -> Result<FnvHashMap<FolderHash, Folder>> {
Err(MeliError::new("Unimplemented."))
}

24
melib/src/backends/imap.rs

@ -442,7 +442,10 @@ impl MailBackend for ImapType {
}
}
fn create_folder(&mut self, mut path: String) -> Result<Folder> {
fn create_folder(
&mut self,
mut path: String,
) -> Result<(FolderHash, FnvHashMap<FolderHash, Folder>)> {
/* Must transform path to something the IMAP server will accept
*
* Each root mailbox has a hierarchy delimeter reported by the LIST entry. All paths
@ -487,16 +490,13 @@ impl MailBackend for ImapType {
}
let ret: Result<()> = ImapResponse::from(&response).into();
ret?;
let new_hash = get_path_hash!(path.as_str());
folders.clear();
drop(folders);
self.folders().map_err(|err| format!("Mailbox create was succesful (returned `{}`) but listing mailboxes afterwards returned `{}`", response, err))?;
let new_hash = get_path_hash!(path.as_str());
Ok(BackendFolder::clone(
&self.folders.read().unwrap()[&new_hash],
))
Ok((new_hash, self.folders().map_err(|err| MeliError::new(format!("Mailbox create was succesful (returned `{}`) but listing mailboxes afterwards returned `{}`", response, err)))?))
}
fn delete_folder(&mut self, folder_hash: FolderHash) -> Result<()> {
fn delete_folder(&mut self, folder_hash: FolderHash) -> Result<FnvHashMap<FolderHash, Folder>> {
let mut folders = self.folders.write().unwrap();
let permissions = folders[&folder_hash].permissions();
if !permissions.delete_mailbox {
@ -541,12 +541,10 @@ impl MailBackend for ImapType {
conn_lck.read_response(&mut response)?;
}
let ret: Result<()> = ImapResponse::from(&response).into();
if ret.is_ok() {
folders.clear();
drop(folders);
self.folders().map_err(|err| format!("Mailbox delete was succesful (returned `{}`) but listing mailboxes afterwards returned `{}`", response, err))?;
}
ret
ret?;
folders.clear();
drop(folders);
self.folders().map_err(|err| format!("Mailbox delete was succesful (returned `{}`) but listing mailboxes afterwards returned `{}`", response, err).into())
}
fn set_folder_subscription(&mut self, folder_hash: FolderHash, new_val: bool) -> Result<()> {

18
melib/src/backends/maildir/backend.rs

@ -636,7 +636,10 @@ impl MailBackend for MaildirType {
self
}
fn create_folder(&mut self, new_path: String) -> Result<Folder> {
fn create_folder(
&mut self,
new_path: String,
) -> Result<(FolderHash, FnvHashMap<FolderHash, Folder>)> {
let mut path = self.path.clone();
path.push(&new_path);
if !path.starts_with(&self.path) {
@ -655,6 +658,11 @@ impl MailBackend for MaildirType {
});
let folder_hash = get_path_hash!(&path);
if let Some(parent) = parent {
self.folders
.entry(parent)
.and_modify(|entry| entry.children.push(folder_hash));
}
let new_folder = MaildirFolder {
hash: folder_hash,
path: PathBuf::from(&new_path),
@ -669,12 +677,14 @@ impl MailBackend for MaildirType {
total: Default::default(),
};
let ret = BackendFolder::clone(debug!(&new_folder));
self.folders.insert(folder_hash, new_folder);
Ok(ret)
Ok((folder_hash, self.folders()?))
}
fn delete_folder(&mut self, _folder_hash: FolderHash) -> Result<()> {
fn delete_folder(
&mut self,
_folder_hash: FolderHash,
) -> Result<FnvHashMap<FolderHash, Folder>> {
Err(MeliError::new("Unimplemented."))
}

12
melib/src/collection.rs

@ -354,16 +354,12 @@ impl Collection {
self.message_ids
.insert(envelope.message_id().raw().to_vec(), hash);
self.envelopes.write().unwrap().insert(hash, envelope);
if !self
.threads
self.threads
.entry(folder_hash)
.or_default()
.insert_reply(&mut self.envelopes, hash)
{
self.threads
.entry(folder_hash)
.or_default()
.insert(&mut self.envelopes, hash);
.insert(&mut self.envelopes, hash);
if self.sent_folder.map(|f| f == folder_hash).unwrap_or(false) {
self.insert_reply(hash);
}
}

74
src/conf/accounts.rs

@ -865,7 +865,7 @@ impl Account {
}
match op {
FolderOperation::Create(path) => {
let mut folder = self
let (folder_hash, mut folders) = self
.backend
.write()
.unwrap()
@ -873,40 +873,51 @@ impl Account {
self.sender
.send(ThreadEvent::UIEvent(UIEvent::MailboxCreate((
self.index,
folder.hash(),
folder_hash,
))))
.unwrap();
let mut new = FileFolderConf::default();
new.folder_conf.subscribe = super::ToggleFlag::InternalVal(true);
new.folder_conf.usage = if folder.special_usage() != SpecialUsageMailbox::Normal {
Some(folder.special_usage())
} else {
let tmp = SpecialUsageMailbox::detect_usage(folder.name());
if tmp != Some(SpecialUsageMailbox::Normal) && tmp != None {
let _ = folder.set_special_usage(tmp.unwrap());
}
tmp
};
new.folder_conf.usage =
if folders[&folder_hash].special_usage() != SpecialUsageMailbox::Normal {
Some(folders[&folder_hash].special_usage())
} else {
let tmp = SpecialUsageMailbox::detect_usage(folders[&folder_hash].name());
if tmp != Some(SpecialUsageMailbox::Normal) && tmp != None {
folders.entry(folder_hash).and_modify(|entry| {
let _ = entry.set_special_usage(tmp.unwrap());
});
}
tmp
};
/* if new folder has parent, we need to update its children field */
if let Some(parent_hash) = folders[&folder_hash].parent() {
self.folder_entries.entry(parent_hash).and_modify(|parent| {
parent.ref_folder = folders.remove(&parent_hash).unwrap();
});
}
let folder_hash = folder.hash();
self.folder_entries.insert(
folder_hash,
FolderEntry {
name: folder.path().to_string(),
name: folders[&folder_hash].path().to_string(),
status: MailboxStatus::Parsing(0, 0),
conf: new,
worker: Account::new_worker(
folder.clone(),
folders[&folder_hash].clone(),
&mut self.backend,
&self.work_context,
self.notify_fn.clone(),
),
ref_folder: folder,
ref_folder: folders.remove(&folder_hash).unwrap(),
},
);
self.collection
.threads
.insert(folder_hash, Threads::default());
self.collection
.mailboxes
.insert(folder_hash, Default::default());
build_folders_order(
&mut self.tree,
&self.folder_entries,
@ -927,7 +938,7 @@ impl Account {
} else {
return Err(MeliError::new("Mailbox with that path not found."));
};
self.backend.write().unwrap().delete_folder(folder_hash)?;
let mut folders = self.backend.write().unwrap().delete_folder(folder_hash)?;
self.sender
.send(ThreadEvent::UIEvent(UIEvent::MailboxDelete((
self.index,
@ -944,8 +955,24 @@ impl Account {
self.sent_folder = None;
}
self.collection.threads.remove(&folder_hash);
/* if deleted folder had parent, we need to update its children field */
if let Some(parent_hash) = self
.folder_entries
.remove(&folder_hash)
.unwrap()
.ref_folder
.parent()
{
self.folder_entries.entry(parent_hash).and_modify(|parent| {
parent.ref_folder = folders.remove(&parent_hash).unwrap();
});
}
self.collection.mailboxes.remove(&folder_hash);
self.folder_entries.remove(&folder_hash);
build_folders_order(
&mut self.tree,
&self.folder_entries,
&mut self.folders_order,
);
// FIXME Kill worker as well
// FIXME remove from settings as well
@ -1063,7 +1090,6 @@ fn build_folders_order(
folder_entries: &FnvHashMap<FolderHash, FolderEntry>,
folders_order: &mut Vec<FolderHash>,
) {
let mut stack: SmallVec<[FolderHash; 8]> = SmallVec::new();
tree.clear();
folders_order.clear();
for (h, f) in folder_entries.iter() {
@ -1079,20 +1105,14 @@ fn build_folders_order(
depth,
};
for &c in folder_entries[&h].ref_folder.children() {
node.children.push(rec(c, folder_entries, depth + 1));
if folder_entries.contains_key(&c) {
node.children.push(rec(c, folder_entries, depth + 1));
}
}
node
};
tree.push(rec(*h, &folder_entries, 0));
for &c in f.ref_folder.children() {
stack.push(c);
}
while let Some(next) = stack.pop() {
for c in folder_entries[&next].ref_folder.children() {
stack.push(*c);
}
}
}
}

5
src/plugins/backend.rs

@ -213,7 +213,10 @@ impl MailBackend for PluginBackend {
fn save(&self, _bytes: &[u8], _folder: &str, _flags: Option<Flag>) -> Result<()> {
Err(MeliError::new("Unimplemented."))
}
fn create_folder(&mut self, _name: String) -> Result<Folder> {
fn create_folder(
&mut self,
_name: String,
) -> Result<(FolderHash, FnvHashMap<FolderHash, Folder>)> {
Err(MeliError::new("Unimplemented."))
}
fn tags(&self) -> Option<Arc<RwLock<BTreeMap<u64, String>>>> {

Loading…
Cancel
Save