From f7ec6d6bc5462fc594f65358f57db1b91514f086 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Sat, 3 Aug 2024 14:00:52 +0300 Subject: [PATCH] melib/jmap: implement mailbox rename Signed-off-by: Manos Pitsidianakis --- melib/src/jmap/mod.rs | 53 +++++++++++++++++++++++++++++++++----- melib/src/jmap/protocol.rs | 4 +-- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/melib/src/jmap/mod.rs b/melib/src/jmap/mod.rs index 85691278..3bd44ae4 100644 --- a/melib/src/jmap/mod.rs +++ b/melib/src/jmap/mod.rs @@ -680,13 +680,54 @@ impl MailBackend for JmapType { fn rename_mailbox( &mut self, - _mailbox_hash: MailboxHash, - _new_path: String, + mailbox_hash: MailboxHash, + new_path: String, ) -> ResultFuture { - Err( - Error::new("Renaming mailbox is currently unimplemented for the JMAP backend.") - .set_kind(ErrorKind::NotImplemented), - ) + let store = self.store.clone(); + let mailbox_id: Id = { + let mailboxes_lck = store.mailboxes.read().unwrap(); + let Some(id) = mailboxes_lck.get(&mailbox_hash).map(|m| m.id.clone()) else { + return Err( + Error::new(format!("Mailbox with hash {} not found", mailbox_hash)) + .set_kind(ErrorKind::NotFound), + ); + }; + id + }; + let connection = self.connection.clone(); + Ok(Box::pin(async move { + let mailbox_state = store.mailbox_state.lock().await.clone(); + let mut conn = connection.lock().await; + let mail_account_id = conn.session_guard().await?.mail_account_id(); + let mailbox_set_call = mailbox::MailboxSet::new( + Set::::new(Some(mailbox_state)) + .account_id(mail_account_id) + .update(Some({ + indexmap! { + mailbox_id.clone().into() => serde_json::json!{indexmap! { + "name" => new_path.clone() + }} + } + })), + ); + + let mut req = Request::new(conn.request_no.clone()); + let _prev_seq = req.add_call(&mailbox_set_call).await; + let new_mailboxes = protocol::get_mailboxes(&mut conn, Some(req)).await?; + + let new_mailbox: Mailbox = new_mailboxes + .iter() + .find_map(|(_, m)| { + if m.path() == new_path { + Some(BackendMailbox::clone(m) as Mailbox) + } else { + None + } + }) + .unwrap(); + *store.mailboxes.write().unwrap() = new_mailboxes; + Ok(new_mailbox) + })) } fn create_mailbox( diff --git a/melib/src/jmap/protocol.rs b/melib/src/jmap/protocol.rs index 98ea776f..2f1ca2d3 100644 --- a/melib/src/jmap/protocol.rs +++ b/melib/src/jmap/protocol.rs @@ -128,9 +128,9 @@ pub async fn get_mailboxes( req.add_call(&mailbox_get).await; let res_text = conn.send_request(serde_json::to_string(&req)?).await?; - let mut v: MethodResponse = deserialize_from_str(&res_text)?; + let v: MethodResponse = deserialize_from_str(&res_text)?; conn.store.online_status.update_timestamp(None).await; - let m = GetResponse::::try_from(v.method_responses.remove(0))?; + let m = GetResponse::::try_from(*v.method_responses.last().unwrap())?; let GetResponse:: { list, account_id,