-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathemail_check.rs
93 lines (77 loc) · 2.56 KB
/
email_check.rs
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
use anyhow::{Context, Result};
use check_if_email_exists::{check_email, CheckEmailInput, CheckEmailOutput, Reachable};
use cowstr::CowStr;
use serde::{Deserialize, Serialize};
use serde_variant::to_variant_name;
use super::email_address_parser::EmailAddressWrapped;
const REACHABLE_INVALIDS: &[Reachable] = &[Reachable::Invalid, Reachable::Unknown];
pub struct EmailCheck {}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct EmailCheckIsValid {
pub address_email: CowStr,
pub email: EmailAddressWrapped,
pub is_valid: bool,
pub reasons_failure: Vec<CowStr>,
}
impl EmailCheck {
pub async fn check_single<TInput>(x: TInput) -> Result<(EmailCheckIsValid, CheckEmailOutput)>
where
TInput: AsRef<str> + Into<String>,
{
let result = Self::fetch_state_single(x).await?;
Ok((Self::is_valid(&result)?, result))
}
pub fn is_valid(input: &CheckEmailOutput) -> Result<EmailCheckIsValid> {
let email: EmailAddressWrapped = input.input.as_str().into();
let address_email: CowStr = input.input.clone().into();
let mut reasons_failure: Vec<CowStr> = Vec::new();
#[allow(clippy::collapsible_if)]
// this one is bad: https://github.com/reacherhq/check-if-email-exists/issues/940
if REACHABLE_INVALIDS.contains(&input.is_reachable) {
reasons_failure.push(
format!(
"is_reachable: {}",
to_variant_name(&input.is_reachable).context("is_reachable to_variant_name")?
)
.into(),
);
}
if let Ok(misc) = &input.misc {
if misc.is_disposable {
reasons_failure.push("is_disposable: true".into());
}
}
if let Ok(smtp) = &input.smtp {
if !smtp.can_connect_smtp {
reasons_failure.push("can_connect_smtp: false".into());
}
if smtp.has_full_inbox {
reasons_failure.push("has_full_inbox: true".into());
}
if smtp.is_catch_all {
reasons_failure.push("is_catch_all: true".into());
}
if !smtp.is_deliverable {
reasons_failure.push("is_deliverable: false".into());
}
if smtp.is_disabled {
reasons_failure.push("is_disabled: true".into());
}
}
if !input.syntax.is_valid_syntax {
reasons_failure.push("is_valid_syntax: false".into());
}
Ok(EmailCheckIsValid {
address_email,
email,
is_valid: reasons_failure.is_empty(),
reasons_failure,
})
}
pub async fn fetch_state_single<TInput>(x: TInput) -> Result<CheckEmailOutput>
where
TInput: AsRef<str> + Into<String>,
{
Ok(check_email(&CheckEmailInput::new(x.into())).await)
}
}