Skip to main content

checkmail_rs/
lib.rs

1use crate::Error::{BadFormat, Unexpected};
2use regex::Regex;
3use thiserror::Error;
4
5#[derive(Error, Debug)]
6pub enum Error {
7    #[error("invalid format: {0}")]
8    BadFormat(String),
9    #[error("unexpected error ({0})")]
10    Unexpected(String),
11}
12
13pub fn validate_format(email: impl Into<String>) -> Result<(), Error> {
14    let re = Regex::new(r"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$")
15        .map_err(|e| Unexpected(e.to_string()))?;
16    let email_string = email.into();
17    let ok = re.is_match(&email_string);
18    if !ok {
19        return Err(BadFormat(email_string));
20    }
21    Ok(())
22}
23
24#[cfg(test)]
25mod tests {
26    use super::*;
27
28    struct Sample {
29        mail: String,
30        format: bool,
31        account: bool,
32    }
33
34    fn setup() -> Vec<Sample> {
35        vec![
36            Sample {
37                mail: "florian@carrere.cc".to_string(),
38                format: true,
39                account: true,
40            },
41            Sample {
42                mail: "support@g2mail.com".to_string(),
43                format: true,
44                account: false,
45            },
46            Sample {
47                mail: "florian@carrere.cc ".to_string(),
48                format: false,
49                account: false,
50            },
51            Sample {
52                mail: "test@912-wrong-domain902.com".to_string(),
53                format: true,
54                account: false,
55            },
56            Sample {
57                mail: "0932910-qsdcqozuioqkdmqpeidj8793@gmail.com".to_string(),
58                format: true,
59                account: false,
60            },
61            Sample {
62                mail: " florian@carrere.cc".to_string(),
63                format: false,
64                account: false,
65            },
66            Sample {
67                mail: "@gmail.com".to_string(),
68                format: false,
69                account: false,
70            },
71            Sample {
72                mail: "test@gmail@gmail.com".to_string(),
73                format: false,
74                account: false,
75            },
76            Sample {
77                mail: "test test@gmail.com".to_string(),
78                format: false,
79                account: false,
80            },
81            Sample {
82                mail: " test@gmail.com".to_string(),
83                format: false,
84                account: false,
85            },
86            Sample {
87                mail: "test@wrong domain.com".to_string(),
88                format: false,
89                account: false,
90            },
91            Sample {
92                mail: "é&ààà@gmail.com".to_string(),
93                format: false,
94                account: false,
95            },
96            Sample {
97                mail: "admin@busyboo.com".to_string(),
98                format: true,
99                account: false,
100            },
101            Sample {
102                mail: "a@gmail.fi".to_string(),
103                format: true,
104                account: false,
105            },
106        ]
107    }
108
109    #[test]
110    fn test_validate_format() {
111        let samples = setup();
112        for s in samples.iter() {
113            let res = validate_format(&s.mail);
114            if s.format {
115                res.expect(format!("expected valid mail: {}", &s.mail).as_str());
116            } else {
117                match res {
118                    Ok(_) => {
119                        panic!(format!("expected invalid mail: {}", &s.mail));
120                    }
121                    Err(e) => {
122                        assert_eq!(e.to_string(), format!("invalid format: {}", &s.mail));
123                    }
124                }
125            }
126        }
127    }
128}