Skip to main content

io_email/mailbox/jmap/
create.rs

1//! JMAP mailbox-create coroutine wrapping Mailbox/set { create }
2//! (RFC 8621 ยง2.6).
3//!
4//! Creates a top-level mailbox; parent/role/sort-order belong to a
5//! protocol-specific extension.
6//!
7//! # Example
8//!
9//! ```rust,ignore
10//! use io_email::mailbox::jmap::create::JmapMailboxCreate;
11//!
12//! client.run(JmapMailboxCreate::new(&session, &auth, "Archive")?)?;
13//! ```
14
15use alloc::{collections::BTreeMap, string::String};
16
17use io_jmap::{
18    coroutine::{JmapCoroutine, JmapCoroutineState, JmapYield},
19    rfc8620::JmapSession,
20    rfc8621::mailbox::{
21        JmapMailboxCreate as Patch,
22        set::{JmapMailboxSet as InnerSet, JmapMailboxSetArgs, JmapMailboxSetError as InnerErr},
23    },
24};
25use log::trace;
26use secrecy::SecretString;
27use thiserror::Error;
28
29/// Errors produced by [`JmapMailboxCreate`].
30#[derive(Debug, Error)]
31pub enum JmapMailboxCreateError {
32    #[error(transparent)]
33    Set(#[from] InnerErr),
34    #[error("Mailbox/set did not create a mailbox for `{0}`")]
35    NotCreated(String),
36}
37
38/// I/O-free coroutine creating a JMAP mailbox named `name`.
39pub struct JmapMailboxCreate {
40    inner: InnerSet,
41    client_id: String,
42}
43
44impl JmapMailboxCreate {
45    pub fn new(
46        session: &JmapSession,
47        http_auth: &SecretString,
48        name: &str,
49    ) -> Result<Self, JmapMailboxCreateError> {
50        trace!("prepare JMAP mailbox create");
51        let client_id = String::from("new");
52        let mut create = BTreeMap::new();
53        create.insert(
54            client_id.clone(),
55            Patch {
56                name: Some(name.into()),
57                ..Patch::default()
58            },
59        );
60        let args = JmapMailboxSetArgs {
61            create: Some(create),
62            ..JmapMailboxSetArgs::default()
63        };
64        let inner = InnerSet::new(session, http_auth, args)?;
65        Ok(Self { inner, client_id })
66    }
67}
68
69impl JmapCoroutine for JmapMailboxCreate {
70    type Yield = JmapYield;
71    type Return = Result<(), JmapMailboxCreateError>;
72
73    fn resume(&mut self, bytes: Option<&[u8]>) -> JmapCoroutineState<Self::Yield, Self::Return> {
74        match self.inner.resume(bytes) {
75            JmapCoroutineState::Yielded(y) => JmapCoroutineState::Yielded(y),
76            JmapCoroutineState::Complete(Ok(ok)) => {
77                if ok.created.contains_key(&self.client_id) {
78                    JmapCoroutineState::Complete(Ok(()))
79                } else {
80                    JmapCoroutineState::Complete(Err(JmapMailboxCreateError::NotCreated(
81                        self.client_id.clone(),
82                    )))
83                }
84            }
85            JmapCoroutineState::Complete(Err(err)) => JmapCoroutineState::Complete(Err(err.into())),
86        }
87    }
88}