use std::{fmt, str::FromStr}; use crate::prelude::Host; #[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 { 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 { let username = username.to_string(); if let Some((h, b)) = host.split_once(|c: char| c.is_whitespace()) { if h.is_empty() { return Err(Error::EmptyHost); } else { host = h; if !b.is_empty() { blurb = Some(b.to_string()); } } } let host = host.parse()?; Ok(Self { username, host, blurb }) } } else { Err(Error::MissingSeparator) } } }