use async_smtp::EmailAddress;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub struct SyntaxDetails {
pub address: Option<EmailAddress>,
pub domain: String,
pub is_valid_syntax: bool,
pub username: String,
}
impl Default for SyntaxDetails {
fn default() -> Self {
SyntaxDetails {
address: None,
domain: "".into(),
is_valid_syntax: false,
username: "".into(),
}
}
}
pub fn check_syntax(email_address: &str) -> SyntaxDetails {
let email_address = match EmailAddress::from_str(email_address) {
Ok(m) => m,
_ => {
return SyntaxDetails {
address: None,
domain: "".into(),
is_valid_syntax: false,
username: "".into(),
}
}
};
let iter: &str = email_address.as_ref();
let mut iter = iter.split('@');
let username = iter
.next()
.expect("We checked above that email is valid. qed.")
.into();
let domain = iter
.next()
.expect("We checked above that email is valid. qed.")
.into();
SyntaxDetails {
address: Some(email_address),
domain,
is_valid_syntax: true,
username,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn should_return_invalid_for_invalid_email() {
assert_eq!(
check_syntax("foo"),
SyntaxDetails {
address: None,
domain: "".into(),
is_valid_syntax: false,
username: "".into(),
}
);
}
#[test]
fn should_return_invalid_for_invalid_email_with_at() {
assert_eq!(
check_syntax("foo@bar"),
SyntaxDetails {
address: None,
domain: "".into(),
is_valid_syntax: false,
username: "".into(),
}
);
}
#[test]
fn should_work_for_valid_email() {
assert_eq!(
check_syntax("foo@bar.com"),
SyntaxDetails {
address: Some(EmailAddress::new("foo@bar.com".into()).unwrap()),
domain: "bar.com".into(),
is_valid_syntax: true,
username: "foo".into(),
}
);
}
}