melib/jmap: implement Backend::create_mailbox()

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
pull/279/head
Manos Pitsidianakis 2023-08-28 14:34:32 +03:00
parent 31982931f5
commit 29fd8522e6
Signed by: Manos Pitsidianakis
GPG Key ID: 7729C7707F7E09D0
2 changed files with 103 additions and 5 deletions

View File

@ -584,11 +584,48 @@ impl MailBackend for JmapType {
fn create_mailbox(
&mut self,
_path: String,
path: String,
) -> ResultFuture<(MailboxHash, HashMap<MailboxHash, Mailbox>)> {
Err(Error::new(
"Creating mailbox is currently unimplemented for the JMAP backend.",
))
let store = self.store.clone();
let connection = self.connection.clone();
Ok(Box::pin(async move {
let mut conn = connection.lock().await;
let mailbox_set_call: MailboxSet = MailboxSet::new(
Set::<MailboxObject>::new()
.account_id(conn.mail_account_id())
.create(Some({
let id: Id<MailboxObject> = path.as_str().into();
indexmap! {
id.clone().into() => MailboxObject {
id,
name: path.clone(),
..MailboxObject::default()
}
}
})),
);
let mut req = Request::new(conn.request_no.clone());
let _prev_seq = req.add_call(&mailbox_set_call);
let new_mailboxes = protocol::get_mailboxes(&mut conn, Some(req)).await?;
*store.mailboxes.write().unwrap() = new_mailboxes;
let new_mailboxes: HashMap<MailboxHash, Mailbox> = store
.mailboxes
.read()
.unwrap()
.iter()
.filter(|(_, f)| f.is_subscribed)
.map(|(&h, f)| (h, BackendMailbox::clone(f) as Mailbox))
.collect();
let id = new_mailboxes
.values()
.find(|m| m.path() == path)
.map(|m| m.hash())
.unwrap();
Ok((id, new_mailboxes))
}))
}
fn delete_mailbox(

View File

@ -27,7 +27,7 @@ impl Id<MailboxObject> {
}
}
#[derive(Deserialize, Serialize, Debug)]
#[derive(Deserialize, Serialize, Debug, Default)]
#[serde(rename_all = "camelCase")]
pub struct MailboxObject {
pub id: Id<MailboxObject>,
@ -60,6 +60,23 @@ pub struct JmapRights {
pub may_set_seen: bool,
pub may_submit: bool,
}
impl Default for JmapRights {
fn default() -> Self {
Self {
may_add_items: true,
may_create_child: true,
may_delete: true,
may_read_items: true,
may_remove_items: true,
may_rename: true,
may_set_keywords: true,
may_set_seen: true,
may_submit: true,
}
}
}
#[derive(Deserialize, Serialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct MailboxGet {
@ -75,3 +92,47 @@ impl MailboxGet {
impl Method<MailboxObject> for MailboxGet {
const NAME: &'static str = "Mailbox/get";
}
/// 2.5. Mailbox/set
///
/// This is a standard `/set` method as described in `[RFC8620]`,
/// Section 5.3 but with the following additional request argument:
///
///
/// The following extra SetError types are defined:
///
/// For `destroy`:
///
/// - `mailboxHasChild`: The Mailbox still has at least one child Mailbox. The
/// client MUST remove these before it can delete the parent Mailbox.
///
/// - `mailboxHasEmail`: The Mailbox has at least one Email assigned to it, and
/// the `onDestroyRemoveEmails` argument was false.
#[derive(Deserialize, Serialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct MailboxSet {
#[serde(flatten)]
pub set_call: Set<MailboxObject>,
/// onDestroyRemoveEmails: `Boolean` (default: false)
///
/// If false, any attempt to destroy a Mailbox that still has Emails
/// in it will be rejected with a `mailboxHasEmail` SetError. If
/// true, any Emails that were in the Mailbox will be removed from it,
/// and if in no other Mailboxes, they will be destroyed when the
/// Mailbox is destroyed.
#[serde(default)]
pub on_destroy_remove_emails: bool,
}
impl MailboxSet {
pub fn new(set_call: Set<MailboxObject>) -> Self {
Self {
set_call,
on_destroy_remove_emails: false,
}
}
}
impl Method<MailboxObject> for MailboxSet {
const NAME: &'static str = "Mailbox/set";
}