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
40 #[serde(deserialize_with="deserialize_only_date")]
41 pub start_date: NaiveDate,
42
43 #[serde(deserialize_with="deserialize_only_date")]
44 pub end_date: NaiveDate,
45}
46
47#[derive(Clone, Debug, Deserialize)]
48pub struct ActivityData {
49 pub found: bool,
50
51 #[serde(deserialize_with="deserialize_stringified_uint")]
52 pub active_in_days: Option<u128>,
53}
54
55#[derive(Clone, Debug, Deserialize)]
56pub struct DomainFormats {
57 pub format: String,
58 pub confidence: String,
59}
60
61#[derive(Clone, Debug, Deserialize)]
62pub struct FindEmailResponse {
63 pub email: String,
64 pub domain: String,
65 pub format: String,
66 pub status: String,
67 pub sub_status: String,
68 pub confidence: String,
69 pub did_you_mean: String,
70 pub failure_reason: String,
71 pub other_domain_formats: Vec<DomainFormats>,
72}
73
74#[derive(Clone, Debug, Deserialize)]
78pub struct FindEmailResponseV2 {
79 pub email: String,
80 #[serde(default)]
81 pub domain: String,
82 #[serde(rename = "email_confidence", default)]
83 pub confidence: String,
84 #[serde(default)]
85 pub company_name: String,
86 #[serde(default)]
87 pub did_you_mean: String,
88 #[serde(default)]
89 pub failure_reason: String,
90}
91
92#[derive(Clone, Debug, Deserialize)]
96pub struct DomainSearchResponseV2 {
97 #[serde(default)]
98 pub domain: String,
99 #[serde(default)]
100 pub company_name: String,
101 #[serde(default)]
102 pub format: String,
103 #[serde(default)]
104 pub confidence: String,
105 #[serde(default)]
106 pub did_you_mean: String,
107 #[serde(default)]
108 pub failure_reason: String,
109 #[serde(default)]
110 pub other_domain_formats: Vec<DomainFormats>,
111}
112
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117 use crate::utility::mock_constants::API_USAGE_RESPONSE;
118 use crate::utility::mock_constants::ACTIVITY_DATA_RESPONSE_ACTIVE;
119 use crate::utility::mock_constants::ACTIVITY_DATA_RESPONSE_INACTIVE;
120 use crate::utility::mock_constants::MOCK_FIND_MAIL_INVALID;
121 use crate::utility::mock_constants::MOCK_FIND_MAIL_VALID;
122
123 #[test]
124 fn parse_activity_date_without_amount() {
125 let activity_data_res = serde_json::from_str::<ActivityData>(
126 ACTIVITY_DATA_RESPONSE_INACTIVE
127 );
128 assert!(activity_data_res.is_ok(), "error: {}", activity_data_res.unwrap_err());
129
130 let activity_data = activity_data_res.unwrap();
131 assert_eq!(activity_data.found, false);
132 assert_eq!(activity_data.active_in_days, None);
133 }
134
135 #[test]
136 fn parse_activity_date_with_amount() {
137 let activity_data_res: serde_json::Result<ActivityData> = serde_json::from_str(ACTIVITY_DATA_RESPONSE_ACTIVE);
138 assert!(activity_data_res.is_ok());
139
140 let activity_data = activity_data_res.unwrap();
141 assert_eq!(activity_data.found, true);
142 assert_eq!(activity_data.active_in_days, Some(180));
143 }
144
145 #[test]
146 fn parse_api_usage() {
147 let api_usage: serde_json::Result<ApiUsage> = serde_json::from_str(API_USAGE_RESPONSE);
148 assert!(api_usage.is_ok());
149
150 let api_usage_obj = api_usage.unwrap();
151 let expected_start_date = NaiveDate::from_ymd_opt(2010, 1, 12).unwrap();
152 let expected_end_date = NaiveDate::from_ymd_opt(2030, 12, 1).unwrap();
153 assert_eq!(api_usage_obj.start_date, expected_start_date);
154 assert_eq!(api_usage_obj.end_date, expected_end_date);
155 }
156
157 #[test]
158 fn parse_find_mail_invalid_status() {
159 let find_mail: serde_json::Result<FindEmailResponse> = serde_json::from_str(MOCK_FIND_MAIL_INVALID);
160 assert!(find_mail.is_ok());
161
162 let find_mail_object = find_mail.unwrap();
163 assert_eq!(find_mail_object.email, "");
164 assert_eq!(find_mail_object.other_domain_formats.len(), 0);
165 }
166
167 #[test]
168 fn parse_find_mail_valid_status() {
169 let find_mail: serde_json::Result<FindEmailResponse> = serde_json::from_str(MOCK_FIND_MAIL_VALID);
170 assert!(find_mail.is_ok());
171
172 let find_mail_object = find_mail.unwrap();
173 assert_eq!(find_mail_object.email, "john.doe@example.com");
174 assert_eq!(find_mail_object.other_domain_formats.len(), 2);
175 assert_eq!(find_mail_object.other_domain_formats[0].confidence, "high");
176 assert_eq!(find_mail_object.other_domain_formats[1].confidence, "medium");
177 }
178
179
180}