76 lines
2.2 KiB
Rust
76 lines
2.2 KiB
Rust
//! 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<String>,
|
|
}
|
|
|
|
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<Self, Self::Err> {
|
|
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<Mailuser> for Mailbox {
|
|
fn from(value: Mailuser) -> Self {
|
|
Self {
|
|
username: value.username,
|
|
host: value.host,
|
|
blurb: None,
|
|
}
|
|
}
|
|
}
|