aboutsummaryrefslogtreecommitdiff
path: root/src/imap/mailbox_view.rs
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2022-07-21 12:44:58 +0200
committerAlex Auvolat <alex@adnab.me>2022-07-21 12:44:58 +0200
commit54c467d3f77fae964400e9c1d78d32d9067c3b0f (patch)
tree4694e2b54d005c5c2283e6a51f530476f4ebac04 /src/imap/mailbox_view.rs
parentdb4ffd7135a3d780cf2f7929e9fb883e96157de4 (diff)
downloadaerogramme-54c467d3f77fae964400e9c1d78d32d9067c3b0f.tar.gz
aerogramme-54c467d3f77fae964400e9c1d78d32d9067c3b0f.zip
Implement COPY
Diffstat (limited to 'src/imap/mailbox_view.rs')
-rw-r--r--src/imap/mailbox_view.rs43
1 files changed, 28 insertions, 15 deletions
diff --git a/src/imap/mailbox_view.rs b/src/imap/mailbox_view.rs
index a886c8d..13ea9a7 100644
--- a/src/imap/mailbox_view.rs
+++ b/src/imap/mailbox_view.rs
@@ -168,6 +168,7 @@ impl MailboxView {
}
}
+ // @TODO: handle _response
self.update().await
}
@@ -189,6 +190,33 @@ impl MailboxView {
self.update().await
}
+ pub async fn copy(
+ &self,
+ sequence_set: &SequenceSet,
+ to: Arc<Mailbox>,
+ is_uid_copy: &bool,
+ ) -> Result<(ImapUidvalidity, Vec<(ImapUid, ImapUid)>)> {
+ let mails = self.get_mail_ids(sequence_set, *is_uid_copy)?;
+
+ let mut new_uuids = vec![];
+ for (_i, _uid, uuid) in mails.iter() {
+ new_uuids.push(to.copy_from(&self.mailbox, *uuid).await?);
+ }
+
+ let mut ret = vec![];
+ let to_state = to.current_uid_index().await;
+ for ((_i, uid, _uuid), new_uuid) in mails.iter().zip(new_uuids.iter()) {
+ let dest_uid = to_state
+ .table
+ .get(new_uuid)
+ .ok_or(anyhow!("copied mail not in destination mailbox"))?
+ .0;
+ ret.push((*uid, dest_uid));
+ }
+
+ Ok((to_state.uidvalidity, ret))
+ }
+
/// Looks up state changes in the mailbox and produces a set of IMAP
/// responses describing the new state.
pub async fn fetch(
@@ -841,21 +869,6 @@ fn build_imap_email_struct<'a>(msg: &Message<'a>, part: &MessagePart<'a>) -> Res
}
}
-fn count_lines(mut text: &[u8]) -> Result<u32> {
- while text.first().map(u8::is_ascii_whitespace).unwrap_or(false) {
- text = &text[1..];
- }
- while text.last().map(u8::is_ascii_whitespace).unwrap_or(false) {
- text = &text[..text.len() - 1];
- }
- if text.is_empty() {
- Ok(0)
- } else {
- let nlf = text.iter().filter(|x| **x == b'\n').count();
- Ok(u32::try_from(1 + nlf)?)
- }
-}
-
fn try_collect_shime<T>(acc: Result<Vec<T>>, elem: Result<T>) -> Result<Vec<T>> {
match (acc, elem) {
(Err(e), _) | (_, Err(e)) => Err(e),