Skip to main content

io_email/message/maildir/
delete.rs

1//! Maildir message-delete coroutine: adds the Trashed (T) info-section
2//! letter; expunge is the caller's responsibility.
3//!
4//! Wraps [`io_maildir::flag::add::MaildirFlagsAdd`] with
5//! [`MaildirFlag::Trashed`].
6//!
7//! # Example
8//!
9//! ```rust,ignore
10//! use io_email::message::maildir::delete::MaildirMessageDelete;
11//!
12//! client.run(MaildirMessageDelete::new(&client.store, "INBOX", "msg-id")?)?;
13//! ```
14//!
15//! [`MaildirFlag::Trashed`]: io_maildir::flag::types::MaildirFlag::Trashed
16
17use core::iter::once;
18
19use io_maildir::{
20    coroutine::*,
21    flag::{
22        add::{MaildirFlagsAdd as InnerAdd, MaildirFlagsAddError as InnerErr},
23        types::MaildirFlag,
24    },
25    maildir::types::Maildir,
26    store::MaildirStore,
27};
28use log::trace;
29use thiserror::Error;
30
31use crate::maildir::convert::{InvalidMailboxName, mailbox_path};
32
33/// Errors produced by [`MaildirMessageDelete`].
34#[derive(Debug, Error)]
35pub enum MaildirMessageDeleteError {
36    #[error(transparent)]
37    Trash(#[from] InnerErr),
38    #[error(transparent)]
39    InvalidMailbox(#[from] InvalidMailboxName),
40}
41
42/// I/O-free coroutine flagging a Maildir message as Trashed.
43pub struct MaildirMessageDelete {
44    inner: InnerAdd,
45}
46
47impl MaildirMessageDelete {
48    pub fn new(
49        store: &MaildirStore,
50        mailbox: &str,
51        id: &str,
52    ) -> Result<Self, MaildirMessageDeleteError> {
53        trace!("prepare Maildir message delete (Trashed flag)");
54        let path = mailbox_path(mailbox)?;
55        let maildir = Maildir::from_path(store.resolve(&path));
56        let trashed = once(MaildirFlag::Trashed).collect();
57        Ok(Self {
58            inner: InnerAdd::new(maildir, id, trashed),
59        })
60    }
61}
62
63impl MaildirCoroutine for MaildirMessageDelete {
64    type Yield = MaildirYield;
65    type Return = Result<(), MaildirMessageDeleteError>;
66
67    fn resume(
68        &mut self,
69        arg: Option<MaildirReply>,
70    ) -> MaildirCoroutineState<Self::Yield, Self::Return> {
71        match self.inner.resume(arg) {
72            MaildirCoroutineState::Yielded(y) => MaildirCoroutineState::Yielded(y),
73            MaildirCoroutineState::Complete(r) => {
74                MaildirCoroutineState::Complete(r.map_err(Into::into))
75            }
76        }
77    }
78}