asimov_imap_module/
message.rs1use super::ImapError;
4use imap::types::Fetch;
5use know::classes::EmailMessage;
6use mail_parser::MessageParser;
7
8#[derive(Clone, Debug, Eq, Hash, PartialEq)]
9pub struct ImapMessage {
10 pub pos: usize,
11 pub uid: Option<u32>,
12 pub size: Option<u32>,
13 pub headers: EmailMessage,
14 pub body: Option<String>,
15}
16
17impl TryFrom<&Fetch<'_>> for ImapMessage {
18 type Error = ImapError;
19
20 fn try_from(input: &Fetch) -> Result<Self, Self::Error> {
21 Ok(match input.body() {
22 Some(bytes) => {
23 let message = MessageParser::default()
24 .parse(bytes)
25 .ok_or(ImapError::InvalidMessage)?;
26 let headers: EmailMessage = (&message)
27 .try_into()
28 .map_err(|_| ImapError::InvalidHeaders)?;
29 let body = headers.body.clone();
30 Self {
31 pos: input.message as _,
32 uid: input.uid,
33 size: input.size,
34 headers,
35 body,
36 }
37 },
38 None => {
39 let envelope = input.envelope().unwrap();
40 let mut headers: EmailMessage =
41 envelope.try_into().map_err(|_| ImapError::InvalidHeaders)?;
42 if let Some(subject_bytes) = envelope.subject.as_ref() {
43 headers.subject = rfc2047_decoder::decode(subject_bytes).ok();
44 }
45 Self {
46 pos: input.message as _,
47 uid: input.uid,
48 size: input.size,
49 headers,
50 body: None,
51 }
52 },
53 })
54 }
55}