diff options
Diffstat (limited to 'melib/src/backends/notmuch.rs')
-rw-r--r-- | melib/src/backends/notmuch.rs | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/melib/src/backends/notmuch.rs b/melib/src/backends/notmuch.rs index e33c8756..c8d69c71 100644 --- a/melib/src/backends/notmuch.rs +++ b/melib/src/backends/notmuch.rs @@ -356,10 +356,14 @@ impl NotmuchDb { } path.pop(); - let mut mailboxes = HashMap::default(); + let mut mailboxes = HashMap::with_capacity(s.mailboxes.len()); + let mut parents: Vec<(MailboxHash, &str)> = Vec::with_capacity(s.mailboxes.len()); for (k, f) in s.mailboxes.iter() { if let Some(query_str) = f.extra.get("query") { let hash = MailboxHash::from_bytes(k.as_bytes()); + if let Some(parent) = f.extra.get("parent") { + parents.push((hash, parent)); + } mailboxes.insert( hash, NotmuchMailbox { @@ -383,6 +387,27 @@ impl NotmuchDb { .set_kind(ErrorKind::Configuration)); } } + for (hash, parent) in parents { + if let Some(&parent_hash) = mailboxes + .iter() + .find(|(_, v)| v.name == parent) + .map(|(k, _)| k) + { + mailboxes + .entry(parent_hash) + .or_default() + .children + .push(hash); + mailboxes.entry(hash).or_default().parent = Some(parent_hash); + } else { + return Err(Error::new(format!( + "Mailbox configuration for `{}` defines its parent mailbox as `{}` but no mailbox exists with this exact name.", + mailboxes[&hash].name(), + parent + )) + .set_kind(ErrorKind::Configuration)); + } + } let account_hash = AccountHash::from_bytes(s.name().as_bytes()); Ok(Box::new(NotmuchDb { @@ -439,6 +464,7 @@ impl NotmuchDb { )).set_kind(ErrorKind::Configuration)); } } + let mut parents: Vec<(String, String)> = Vec::with_capacity(s.mailboxes.len()); for (k, f) in s.mailboxes.iter_mut() { if f.extra.remove("query").is_none() { return Err(Error::new(format!( @@ -448,6 +474,34 @@ impl NotmuchDb { )) .set_kind(ErrorKind::Configuration)); } + if let Some(parent) = f.extra.remove("parent") { + parents.push((k.clone(), parent)); + } + } + let mut path = Vec::with_capacity(8); + for (mbox, parent) in parents.iter() { + if !s.mailboxes.contains_key(parent) { + return Err(Error::new(format!( + "Mailbox configuration for `{}` defines its parent mailbox as `{}` but no mailbox exists with this exact name.", + mbox, + parent + )) + .set_kind(ErrorKind::Configuration)); + } + path.clear(); + path.push(mbox.as_str()); + let mut iter = parent.as_str(); + while let Some((k, v)) = parents.iter().find(|(k, _v)| k == iter) { + if k == mbox { + return Err(Error::new(format!( + "Found cycle in mailbox hierarchy: {}", + path.join("->") + )) + .set_kind(ErrorKind::Configuration)); + } + path.push(k.as_str()); + iter = v.as_str(); + } } Ok(()) } |