Skip to main content

io_email/message/m2dir/
get.rs

1//! m2dir message-get coroutine wrapping
2//! [`io_m2dir::entry::get::M2dirEntryGet`]: locates the entry file by
3//! id, validates the checksum, and returns raw RFC 5322 bytes.
4//!
5//! # Example
6//!
7//! ```rust,ignore
8//! use io_email::message::m2dir::get::M2dirMessageGet;
9//!
10//! let raw = client.run(M2dirMessageGet::new(&client.root, "INBOX", "msg-id")?)?;
11//! ```
12
13use alloc::vec::Vec;
14use std::path::PathBuf;
15
16use io_m2dir::{
17    coroutine::*,
18    entry::get::{
19        M2dirEntryGet as InnerGet, M2dirEntryGetError as InnerErr,
20        M2dirEntryGetOptions as InnerOpts,
21    },
22};
23use log::trace;
24use thiserror::Error;
25
26use crate::m2dir::convert::{InvalidMailboxName, resolve_mailbox};
27
28/// Errors produced by [`M2dirMessageGet`].
29#[derive(Debug, Error)]
30pub enum M2dirMessageGetError {
31    #[error(transparent)]
32    Get(#[from] InnerErr),
33    #[error(transparent)]
34    InvalidMailbox(#[from] InvalidMailboxName),
35}
36
37/// I/O-free coroutine reading a single m2dir message as raw bytes.
38pub struct M2dirMessageGet {
39    inner: InnerGet,
40}
41
42impl M2dirMessageGet {
43    pub fn new(
44        root: impl Into<PathBuf>,
45        mailbox: &str,
46        id: &str,
47    ) -> Result<Self, M2dirMessageGetError> {
48        trace!("prepare m2dir message get");
49        let m2dir = resolve_mailbox(root, mailbox)?;
50        Ok(Self {
51            inner: InnerGet::new(m2dir, id, InnerOpts::default()),
52        })
53    }
54}
55
56impl M2dirCoroutine for M2dirMessageGet {
57    type Yield = M2dirYield;
58    type Return = Result<Vec<u8>, M2dirMessageGetError>;
59
60    fn resume(&mut self, arg: Option<M2dirArg>) -> M2dirCoroutineState<Self::Yield, Self::Return> {
61        match self.inner.resume(arg) {
62            M2dirCoroutineState::Yielded(y) => M2dirCoroutineState::Yielded(y),
63            M2dirCoroutineState::Complete(Ok(out)) => {
64                M2dirCoroutineState::Complete(Ok(out.contents))
65            }
66            M2dirCoroutineState::Complete(Err(err)) => {
67                M2dirCoroutineState::Complete(Err(err.into()))
68            }
69        }
70    }
71}