zero_bounce/utility/structures/
generic.rs1use chrono::NaiveDate;
2use serde::Deserialize;
3
4use crate::utility::structures::custom_deserialize::deserialize_only_date;
5use crate::utility::structures::custom_deserialize::deserialize_stringified_uint;
6
7#[derive(Clone, Debug, Deserialize)]
8pub struct ApiUsage {
9 pub total: u64,
10 pub status_valid: u64,
11 pub status_invalid: u64,
12 pub status_catch_all: u64,
13 pub status_do_not_mail: u64,
14 pub status_spamtrap: u64,
15 pub status_unknown: u64,
16 pub sub_status_toxic: u64,
17 pub sub_status_disposable: u64,
18 pub sub_status_role_based: u64,
19 pub sub_status_possible_trap: u64,
20 pub sub_status_global_suppression: u64,
21 pub sub_status_timeout_exceeded: u64,
22 pub sub_status_mail_server_temporary_error: u64,
23 pub sub_status_mail_server_did_not_respond: u64,
24 pub sub_status_greylisted: u64,
25 pub sub_status_antispam_system: u64,
26 pub sub_status_does_not_accept_mail: u64,
27 pub sub_status_exception_occurred: u64,
28 pub sub_status_failed_syntax_check: u64,
29 pub sub_status_mailbox_not_found: u64,
30 pub sub_status_unroutable_ip_address: u64,
31 pub sub_status_possible_typo: u64,
32 pub sub_status_no_dns_entries: u64,
33 pub sub_status_role_based_catch_all: u64,
34 pub sub_status_accept_all: u64,
35 pub sub_status_mailbox_quota_exceeded: u64,
36 pub sub_status_forcible_disconnect: u64,
37 pub sub_status_failed_smtp_connection: u64,
38 pub sub_status_mx_forward: u64,
39 pub sub_status_alternate: u64,
40 pub sub_status_allowed: u64,
41 pub sub_status_blocked: u64,
42 pub sub_status_gold: u64,
43 pub sub_status_role_based_accept_all: u64,
44
45 #[serde(deserialize_with="deserialize_only_date")]
46 pub start_date: NaiveDate,
47
48 #[serde(deserialize_with="deserialize_only_date")]
49 pub end_date: NaiveDate,
50}
51
52#[derive(Clone, Debug, Deserialize)]
53pub struct ActivityData {
54 pub found: bool,
55
56 #[serde(deserialize_with="deserialize_stringified_uint")]
57 pub active_in_days: Option<u128>,
58}
59
60#[derive(Clone, Debug, Deserialize)]
61pub struct DomainFormats {
62 pub format: String,
63 pub confidence: String,
64}
65
66#[derive(Clone, Debug, Deserialize)]
67pub struct FindEmailResponse {
68 pub email: String,
69 pub domain: String,
70 pub format: String,
71 pub status: String,
72 pub sub_status: String,
73 pub confidence: String,
74 pub did_you_mean: String,
75 pub failure_reason: String,
76 pub other_domain_formats: Vec<DomainFormats>,
77}
78
79#[derive(Clone, Debug, Deserialize)]
83pub struct FindEmailResponseV2 {
84 pub email: String,
85 #[serde(default)]
86 pub domain: String,
87 #[serde(rename = "email_confidence", default)]
88 pub confidence: String,
89 #[serde(default)]
90 pub company_name: String,
91 #[serde(default)]
92 pub did_you_mean: String,
93 #[serde(default)]
94 pub failure_reason: String,
95}
96
97#[derive(Clone, Debug, Deserialize)]
101pub struct DomainSearchResponseV2 {
102 #[serde(default)]
103 pub domain: String,
104 #[serde(default)]
105 pub company_name: String,
106 #[serde(default)]
107 pub format: String,
108 #[serde(default)]
109 pub confidence: String,
110 #[serde(default)]
111 pub did_you_mean: String,
112 #[serde(default)]
113 pub failure_reason: String,
114 #[serde(default)]
115 pub other_domain_formats: Vec<DomainFormats>,
116}
117
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122 use crate::utility::mock_constants::API_USAGE_RESPONSE;
123 use crate::utility::mock_constants::ACTIVITY_DATA_RESPONSE_ACTIVE;
124 use crate::utility::mock_constants::ACTIVITY_DATA_RESPONSE_INACTIVE;
125 use crate::utility::mock_constants::MOCK_FIND_MAIL_INVALID;
126 use crate::utility::mock_constants::MOCK_FIND_MAIL_VALID;
127
128 #[test]
129 fn parse_activity_date_without_amount() {
130 let activity_data_res = serde_json::from_str::<ActivityData>(
131 ACTIVITY_DATA_RESPONSE_INACTIVE
132 );
133 assert!(activity_data_res.is_ok(), "error: {}", activity_data_res.unwrap_err());
134
135 let activity_data = activity_data_res.unwrap();
136 assert_eq!(activity_data.found, false);
137 assert_eq!(activity_data.active_in_days, None);
138 }
139
140 #[test]
141 fn parse_activity_date_with_amount() {
142 let activity_data_res: serde_json::Result<ActivityData> = serde_json::from_str(ACTIVITY_DATA_RESPONSE_ACTIVE);
143 assert!(activity_data_res.is_ok());
144
145 let activity_data = activity_data_res.unwrap();
146 assert_eq!(activity_data.found, true);
147 assert_eq!(activity_data.active_in_days, Some(180));
148 }
149
150 #[test]
151 fn parse_api_usage() {
152 let api_usage: serde_json::Result<ApiUsage> = serde_json::from_str(API_USAGE_RESPONSE);
153 assert!(api_usage.is_ok());
154
155 let api_usage_obj = api_usage.unwrap();
156 let expected_start_date = NaiveDate::from_ymd_opt(2010, 1, 12).unwrap();
157 let expected_end_date = NaiveDate::from_ymd_opt(2030, 12, 1).unwrap();
158 assert_eq!(api_usage_obj.start_date, expected_start_date);
159 assert_eq!(api_usage_obj.end_date, expected_end_date);
160 }
161
162 #[test]
163 fn parse_find_mail_invalid_status() {
164 let find_mail: serde_json::Result<FindEmailResponse> = serde_json::from_str(MOCK_FIND_MAIL_INVALID);
165 assert!(find_mail.is_ok());
166
167 let find_mail_object = find_mail.unwrap();
168 assert_eq!(find_mail_object.email, "");
169 assert_eq!(find_mail_object.other_domain_formats.len(), 0);
170 }
171
172 #[test]
173 fn parse_find_mail_valid_status() {
174 let find_mail: serde_json::Result<FindEmailResponse> = serde_json::from_str(MOCK_FIND_MAIL_VALID);
175 assert!(find_mail.is_ok());
176
177 let find_mail_object = find_mail.unwrap();
178 assert_eq!(find_mail_object.email, "john.doe@example.com");
179 assert_eq!(find_mail_object.other_domain_formats.len(), 2);
180 assert_eq!(find_mail_object.other_domain_formats[0].confidence, "high");
181 assert_eq!(find_mail_object.other_domain_formats[1].confidence, "medium");
182 }
183
184
185}