1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use crate::util::ser_with_display;
use lettre::error::Error as LettreError;
use lettre::EmailAddress;
use serde::Serialize;
use std::str::FromStr;
#[derive(Debug, PartialEq, Serialize)]
pub struct SyntaxDetails {
pub address: EmailAddress,
pub domain: String,
pub username: String,
pub valid_format: bool,
}
#[derive(Debug, Serialize)]
#[serde(tag = "type", content = "message")]
pub enum SyntaxError {
#[serde(serialize_with = "ser_with_display")]
SyntaxError(LettreError),
}
impl PartialEq for SyntaxError {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(
SyntaxError::SyntaxError(LettreError::InvalidEmailAddress),
SyntaxError::SyntaxError(LettreError::InvalidEmailAddress),
) => true,
_ => false,
}
}
}
pub fn address_syntax(email_address: &str) -> Result<SyntaxDetails, SyntaxError> {
let email_address = match EmailAddress::from_str(email_address) {
Ok(m) => m,
Err(error) => return Err(SyntaxError::SyntaxError(error)),
};
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();
let address_details = SyntaxDetails {
address: email_address,
domain,
username,
valid_format: true,
};
Ok(address_details)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn should_return_error_for_invalid_email() {
assert_eq!(
address_syntax("foo"),
Err(SyntaxError::SyntaxError(LettreError::InvalidEmailAddress))
);
}
#[test]
fn should_return_error_for_invalid_email_with_at() {
assert_eq!(
address_syntax("foo@bar"),
Err(SyntaxError::SyntaxError(LettreError::InvalidEmailAddress))
);
}
#[test]
fn should_work_for_valid_email() {
assert_eq!(
address_syntax("foo@bar.com"),
Ok(SyntaxDetails {
address: EmailAddress::new("foo@bar.com".into()).unwrap(),
domain: "bar.com".into(),
username: "foo".into(),
valid_format: true
})
);
}
}