Skip to main content

io_email/message/maildir/
get.rs

1//! Maildir message-get coroutine wrapping
2//! [`io_maildir::entry::get::MaildirEntryGet`]: locates the message
3//! across cur/new/tmp and returns raw RFC 5322 bytes.
4//!
5//! # Example
6//!
7//! ```rust,ignore
8//! use io_email::message::maildir::get::MaildirMessageGet;
9//!
10//! let raw = client.run(MaildirMessageGet::new(&client.store, "INBOX", "msg-id")?)?;
11//! ```
12
13use alloc::vec::Vec;
14
15use io_maildir::{
16    coroutine::*,
17    entry::get::{
18        MaildirEntryGet as InnerMaildirMessageGet,
19        MaildirEntryGetError as InnerMaildirMessageGetError,
20    },
21    maildir::types::Maildir,
22    store::MaildirStore,
23};
24use log::trace;
25use thiserror::Error;
26
27use crate::maildir::convert::{InvalidMailboxName, mailbox_path};
28
29/// Errors produced by [`MaildirMessageGet`].
30#[derive(Debug, Error)]
31pub enum MaildirMessageGetError {
32    #[error(transparent)]
33    Get(#[from] InnerMaildirMessageGetError),
34    #[error(transparent)]
35    InvalidMailbox(#[from] InvalidMailboxName),
36}
37
38/// I/O-free coroutine reading a single Maildir message as raw bytes.
39pub struct MaildirMessageGet {
40    inner: InnerMaildirMessageGet,
41}
42
43impl MaildirMessageGet {
44    pub fn new(
45        store: &MaildirStore,
46        mailbox: &str,
47        id: &str,
48    ) -> Result<Self, MaildirMessageGetError> {
49        trace!("prepare Maildir message get");
50        let path = mailbox_path(mailbox)?;
51        let maildir = Maildir::from_path(store.resolve(&path));
52        Ok(Self {
53            inner: InnerMaildirMessageGet::new(maildir, id),
54        })
55    }
56}
57
58impl MaildirCoroutine for MaildirMessageGet {
59    type Yield = MaildirYield;
60    type Return = Result<Vec<u8>, MaildirMessageGetError>;
61
62    fn resume(
63        &mut self,
64        arg: Option<MaildirReply>,
65    ) -> MaildirCoroutineState<Self::Yield, Self::Return> {
66        match self.inner.resume(arg) {
67            MaildirCoroutineState::Yielded(y) => MaildirCoroutineState::Yielded(y),
68            MaildirCoroutineState::Complete(Ok(entry)) => {
69                MaildirCoroutineState::Complete(Ok(entry.into()))
70            }
71            MaildirCoroutineState::Complete(Err(err)) => {
72                MaildirCoroutineState::Complete(Err(err.into()))
73            }
74        }
75    }
76}