//! A full representation of a Misfin mailbox, including display name use crate::{mailuser::Mailuser, prelude::Host}; use std::{fmt, str::FromStr}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; mod error; pub use error::Error; #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] pub struct Mailbox { pub username: String, pub host: Host, pub blurb: Option, } impl fmt::Display for Mailbox { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if let Some(ref blurb) = self.blurb { write!(f, "{}@{} {}", self.username, self.host, blurb,) } else { write!(f, "{}@{}", self.username, self.host,) } } } impl FromStr for Mailbox { type Err = Error; fn from_str(s: &str) -> Result { let mut blurb = None; if let Some((username, mut host)) = s.split_once('@') { if username.is_empty() { Err(Error::EmptyUser) } else if username.contains(char::is_whitespace) { Err(Error::IllegalWhitespace) } else { let username = username.to_string(); if let Some((h, b)) = host.split_once(char::is_whitespace) { if h.is_empty() { return Err(Error::EmptyHost); } else if h.contains(char::is_whitespace) { return Err(Error::IllegalWhitespace); } host = h; if !b.is_empty() { if b.contains('\n') { return Err(Error::IllegalWhitespace); } blurb = Some(b.to_string()); } } let host = host.parse()?; Ok(Self { username, host, blurb, }) } } else { Err(Error::MissingSeparator) } } } impl From for Mailbox { fn from(value: Mailuser) -> Self { Self { username: value.username, host: value.host, blurb: None, } } }