Skip to main content

io_email/mailbox/imap/
create.rs

1//! IMAP mailbox-create coroutine wrapping CREATE (RFC 3501 ยง6.3.3).
2//!
3//! # Example
4//!
5//! ```rust,ignore
6//! use io_email::mailbox::imap::create::ImapMailboxCreate;
7//!
8//! client.run(ImapMailboxCreate::new("Archive")?)?;
9//! ```
10
11use alloc::string::String;
12
13use io_imap::{
14    codec::fragmentizer::Fragmentizer,
15    coroutine::{ImapCoroutine, ImapCoroutineState, ImapYield},
16    rfc3501::create::{
17        ImapMailboxCreate as InnerImapMailboxCreate,
18        ImapMailboxCreateError as InnerImapMailboxCreateError,
19    },
20};
21use log::trace;
22use thiserror::Error;
23
24use crate::imap::convert::{InvalidMailboxName, parse_mailbox};
25
26/// Errors produced by [`ImapMailboxCreate`].
27#[derive(Debug, Error)]
28pub enum ImapMailboxCreateError {
29    #[error(transparent)]
30    Create(#[from] InnerImapMailboxCreateError),
31    #[error("invalid IMAP mailbox `{0}`")]
32    InvalidMailbox(String),
33}
34
35impl From<InvalidMailboxName> for ImapMailboxCreateError {
36    fn from(err: InvalidMailboxName) -> Self {
37        Self::InvalidMailbox(err.0)
38    }
39}
40
41/// I/O-free coroutine creating an IMAP mailbox.
42pub struct ImapMailboxCreate {
43    inner: InnerImapMailboxCreate,
44}
45
46impl ImapMailboxCreate {
47    pub fn new(name: &str) -> Result<Self, ImapMailboxCreateError> {
48        trace!("prepare IMAP mailbox create");
49        let mbox = parse_mailbox(name)?;
50        Ok(Self {
51            inner: InnerImapMailboxCreate::new(mbox),
52        })
53    }
54}
55
56impl ImapCoroutine for ImapMailboxCreate {
57    type Yield = ImapYield;
58    type Return = Result<(), ImapMailboxCreateError>;
59
60    fn resume(
61        &mut self,
62        fragmentizer: &mut Fragmentizer,
63        bytes: Option<&[u8]>,
64    ) -> ImapCoroutineState<Self::Yield, Self::Return> {
65        match self.inner.resume(fragmentizer, bytes) {
66            ImapCoroutineState::Yielded(y) => ImapCoroutineState::Yielded(y),
67            ImapCoroutineState::Complete(r) => ImapCoroutineState::Complete(r.map_err(Into::into)),
68        }
69    }
70}