use std::{fmt, str::FromStr}; use crate::prelude::{Host, Mailbox}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; mod error; pub use error::Error; #[derive(Clone, Debug, PartialEq)] pub struct Recipients { pub boxes: Vec, } impl fmt::Display for Recipients { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, ":")?; self.boxes.iter().try_for_each(|b| { write!(f, " {b}") }) } } #[derive(Clone, Debug, PartialEq)] pub enum Lines { Sender(Mailbox), Recipients(Recipients), Timestamp(String), Text(String), Heading1(String), Heading2(String), Heading3(String), Quote(String), Preformatted(String), } impl fmt::Display for Lines { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Sender(m) => writeln!(f, "< {m}"), Self::Recipients(r) => writeln!(f, "{r}"), Self::Timestamp(t) => writeln!(f, "@ {t}"), Self::Text(t) => writeln!(f, "{t}"), Self::Heading1(h) => writeln!(f, "# {h}"), Self::Heading2(h) => writeln!(f, "## {h}"), Self::Heading3(h) => writeln!(f, "### {h}"), Self::Quote(q) => { for l in q.lines() { writeln!(f, "> {l}")?; } Ok(()) }, Self::Preformatted(p) => writeln!(f, "```\n{p}\n```"), } } } #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] pub struct Message { pub senders: Vec, pub recipients: Vec, pub timstamp: Option, pub body: String, } impl fmt::Display for Message { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if !self.senders.is_empty() { write!(f, "< ")?; self.senders.iter().try_for_each(|s| { write!(f, "{s}\n") })?; } if !self.recipients.is_empty() { write!(f, ": ")?; self.recipients.iter().try_for_each(|r| { write!(f, " {r}") })?; write!(f, "\n")?; } write!(f, "{}\r\n", self.body) } }