xmail/
lib.rs

1#![feature(let_chains)]
2use xstr::cut255 as cut;
3
4pub fn user_host(mail: impl AsRef<str>) -> (String, String) {
5  let mail = mail.as_ref();
6  let user;
7
8  if let Some(p) = mail.find('@') {
9    user = cut(&mail[..p]).to_owned();
10    if mail.len() > p {
11      return (user, cut(&mail[p + 1..]).into());
12    }
13  } else {
14    user = "".to_owned();
15  }
16
17  (user, cut(mail).into())
18}
19
20pub fn norm_user_host(mail: impl AsRef<str>) -> (String, String) {
21  let mail = xstr::lowtrim(mail);
22  let (user, host) = user_host(mail);
23  let host = host
24    .split('.')
25    .map(|i| {
26      let i = i.trim();
27      if i.starts_with("xn--")
28        && let Ok(i) = punycode::decode(&i[3..])
29      {
30        i
31      } else {
32        i.to_owned()
33      }
34    })
35    .collect::<Vec<_>>()
36    .join(".");
37  (user, host)
38}
39
40pub fn norm(mail: impl AsRef<str>) -> String {
41  let (user, host) = norm_user_host(mail);
42  user + "@" + &host
43}
44
45pub fn norm_tld(mail: impl AsRef<str>) -> (String, String) {
46  let (user, host) = norm_user_host(mail);
47  (user + "@" + &host, xtld::tld(&host).into())
48}