use std::collections::HashMap;
use serde::Serialize;
use serde_json::from_str;
use serde_json::{Map as SerdeMap, Value};
use crate::{ZeroBounce, ZBResult};
use crate::utility::{ENDPOINT_VALIDATE, ZBError, ENDPOINT_BATCH_VALIDATE};
use crate::utility::structures::validation::{ZBValidation, ZBBatchValidation};
impl ZeroBounce {
pub fn validate_email_and_ip(&self, email: &str, ip_address: &str) -> ZBResult<ZBValidation> {
let mut query_args = HashMap::from([
("api_key", self.api_key.as_str()),
("email", email),
]);
if ip_address.len() != 0 {
query_args.insert("ip_address", ip_address);
}
let response_content = self.generic_get_request(
ENDPOINT_VALIDATE, query_args
)?;
let validation = from_str::<ZBValidation>(&response_content)?;
Ok(validation)
}
pub fn validate_email(&self, email: &str) -> ZBResult<ZBValidation> {
return self.validate_email_and_ip(email, "");
}
fn batch_validate_prepare_body(&self, emails_and_ip_addresses: Vec<(String, String)>) -> ZBResult<String> {
let email_batch = emails_and_ip_addresses
.into_iter()
.map(|(email, ip_address)|
[
("email_address".to_string(), Value::String(email)),
("ip_address".to_string(), Value::String(ip_address)),
]
)
.map(SerdeMap::<String, Value>::from_iter)
.map(Value::Object)
.collect::<Vec<Value>>();
let request_body_map = SerdeMap::from_iter([
("api_key".to_string(), Value::String(self.api_key.clone())),
("email_batch".to_string(), Value::Array(email_batch)),
]);
let mut serializer = serde_json::Serializer::new(Vec::new());
Value::Object(request_body_map)
.serialize(&mut serializer)
.map_err(ZBError::JsonError)?;
let final_string = String::from_utf8(serializer.into_inner())
.map_err(|error| ZBError::explicit(error.to_string().as_str()))?;
Ok(final_string)
}
pub fn batch_validate(&self, emails_and_ip_addresses: Vec<(String, String)>) -> ZBResult<ZBBatchValidation> {
let body_content = self.batch_validate_prepare_body(emails_and_ip_addresses)?;
let url = self.url_provider.url_of(ENDPOINT_BATCH_VALIDATE);
let response = self.client.post(url)
.body(body_content)
.header("content-type", "application/json")
.send()?;
let response_ok = response.status().is_success();
let response_content = response.text()?;
if !response_ok {
return Err(ZBError::explicit(response_content.as_str()));
}
let validation = from_str::<ZBBatchValidation>(response_content.as_str())?;
Ok(validation)
}
}
#[cfg(test)]
mod test {
use crate::ZeroBounce;
#[test]
fn test_serializing_example() {
let emails_and_ip_addresses = vec![
("valid@example.com".to_string(), "123.123.123.123".to_string()),
("invalid@example.com".to_string(), "".to_string()),
];
let body_result = ZeroBounce::new("some_api_key")
.batch_validate_prepare_body(emails_and_ip_addresses);
assert!(body_result.is_ok())
}
}