1use std::collections::HashMap;
2
3use serde_json::from_str;
4
5use crate::ZeroBounce;
6use crate::utility::{ZBResult, ZBError};
7use crate::utility::{CONTENT_TYPE_JSON, CONTENT_TYPE_STREAM};
8use crate::utility::{ENDPOINT_FILE_SEND, ENDPOINT_FILE_STATUS, ENDPOINT_FILE_RESULT, ENDPOINT_FILE_DELETE};
9use crate::utility::{ENDPOINT_SCORING_DELETE, ENDPOINT_SCORING_STATUS, ENDPOINT_SCORING_RESULT, ENDPOINT_SCORING_SEND};
10use crate::utility::structures::bulk::{ZBBulkResponse, ZBFile, ZBFileFeedback, ZBFileStatus};
11
12
13impl ZeroBounce {
14
15 fn generic_file_submit(&self, endpoint: &str, zb_file: &ZBFile) -> ZBResult<ZBFileFeedback> {
16 let multi_part_form = zb_file.generate_multipart()?
17 .text("api_key", self.api_key.clone());
18
19 let url = self.url_provider.bulk_url_of(endpoint);
20 let response = self.client.post(url)
21 .multipart(multi_part_form)
22 .send()?;
23
24 let response_ok = response.status().is_success();
25 let response_content = response.text()?;
26
27 #[cfg(debug_assertions)]
29 {
30 eprintln!("Raw API response: {}", response_content);
31 }
32
33 if !response_ok {
34 return Err(ZBError::ExplicitError(response_content));
35 }
36
37 let feedback_object = from_str::<ZBFileFeedback>(&response_content)?;
38 Ok(feedback_object)
39 }
40
41 fn generic_file_status_check(&self, endpoint: &str, file_id: &str) -> ZBResult<ZBFileStatus> {
42 let query_args = HashMap::from([
43 ("file_id", file_id),
44 ]);
45
46 let response_content = self.generic_get_request(
47 self.url_provider.bulk_url_of(endpoint), query_args
48 )?;
49
50 let file_status = from_str::<ZBFileStatus>(&response_content)?;
51 Ok(file_status)
52 }
53
54 fn generic_result_fetch(&self, endpoint: &str, file_id: &str) -> ZBResult<ZBBulkResponse> {
55 let query_args = HashMap::from([
56 ("file_id", file_id),
57 ]);
58
59 let url = &self.url_provider.bulk_url_of(endpoint);
60 let response = self.client
61 .get(url)
62 .query(&query_args)
63 .send()?;
64
65 let content_type = response
67 .headers()
68 .get("Content-Type")
69 .ok_or(ZBError::explicit("content type not specified in response"))?
70 .to_str()
71 .map_err(|error| ZBError::ExplicitError(error.to_string()))?
72 .to_string();
73
74 let status_amount = response.status().as_u16();
75 if !response.status().is_success() {
76 let response_content = response.text()?;
77 #[cfg(debug_assertions)]
79 {
80 eprintln!("Raw API response: {}", response_content);
81 }
82 return Err(ZBError::ExplicitError(response_content))
83 }
84
85 if content_type == CONTENT_TYPE_STREAM {
86 let content = response.bytes()?;
87 return Ok(ZBBulkResponse::Content(content));
88 }
89
90 let response_content = response.text()?;
91
92 #[cfg(debug_assertions)]
94 {
95 if content_type == CONTENT_TYPE_JSON {
96 eprintln!("Raw API response: {}", response_content);
97 }
98 }
99
100 if content_type == CONTENT_TYPE_JSON {
101 let feedback_res = from_str::<ZBFileFeedback>(&response_content);
102 if let Ok(file_feedback) = feedback_res {
103 return Ok(ZBBulkResponse::Feedback(file_feedback));
104 }
105 }
106
107 let error_ = format!(
109 "Status: {}. Content-type: {}. Response content: {}",
110 status_amount,
111 content_type,
112 response_content,
113 );
114 Err(ZBError::ExplicitError(error_))
115 }
116
117 fn generic_result_delete(&self, endpoint: &str, file_id: &str) -> ZBResult<ZBFileFeedback>{
118 let query_args = HashMap::from([
119 ("file_id", file_id),
120 ]);
121
122 let response_content = self.generic_get_request(
123 self.url_provider.bulk_url_of(endpoint), query_args
124 )?;
125
126 let file_status = from_str::<ZBFileFeedback>(&response_content)?;
127 Ok(file_status)
128 }
129
130 pub fn bulk_validation_file_submit(&self, zb_file: &ZBFile) -> ZBResult<ZBFileFeedback> {
131 self.generic_file_submit(ENDPOINT_FILE_SEND, zb_file)
132 }
133
134 pub fn bulk_validation_file_status_check(&self, file_id: &str) -> ZBResult<ZBFileStatus> {
135 self.generic_file_status_check(ENDPOINT_FILE_STATUS, file_id)
136 }
137
138 pub fn bulk_validation_result_fetch(&self, file_id: &str) -> ZBResult<ZBBulkResponse> {
139 self.generic_result_fetch(ENDPOINT_FILE_RESULT, file_id)
140 }
141
142 pub fn bulk_validation_result_delete(&self, file_id: &str) -> ZBResult<ZBFileFeedback> {
143 self.generic_result_delete(ENDPOINT_FILE_DELETE, file_id)
144 }
145
146 pub fn ai_scoring_file_submit(&self, zb_file: &ZBFile) -> ZBResult<ZBFileFeedback> {
147 self.generic_file_submit(ENDPOINT_SCORING_SEND, zb_file)
148 }
149
150 pub fn ai_scoring_file_status_check(&self, file_id: &str) -> ZBResult<ZBFileStatus> {
151 self.generic_file_status_check(ENDPOINT_SCORING_STATUS, file_id)
152 }
153
154 pub fn ai_scoring_result_fetch(&self, file_id: &str) -> ZBResult<ZBBulkResponse> {
155 self.generic_result_fetch(ENDPOINT_SCORING_RESULT, file_id)
156 }
157
158 pub fn ai_scoring_result_delete(&self, file_id: &str) -> ZBResult<ZBFileFeedback> {
159 self.generic_result_delete(ENDPOINT_SCORING_DELETE, file_id)
160 }
161
162
163}