Skip to main content

zero_bounce/
lib.rs

1pub mod api;
2pub mod utility;
3
4use std::collections::HashMap;
5
6pub use crate::utility::{ZBError, ZBResult, ApiBaseUrl};
7pub use crate::utility::structures::{ActivityData, ApiUsage};
8pub use crate::utility::structures::bulk::{ZBFile, ZBFileFeedback, ZBFileStatus, ZBBulkResponse};
9pub use crate::utility::structures::validate_enums::{ZBValidateStatus, ZBValidateSubStatus};
10pub use crate::api::{FindEmailV2Builder, DomainSearchV2Builder};
11
12// Structure meant to generate the URLs to be accessed with the HTTP requests
13// based on the base API URLs (for the base API and bulk API).
14pub struct ZBUrlProvider {
15    pub url: String,
16    pub bulk_url: String,
17}
18
19impl ZBUrlProvider {
20    pub fn url_of(&self, endpoint: &str) -> String {
21        self.url.to_owned() + endpoint
22    }
23    pub fn bulk_url_of(&self, endpoint: &str) -> String {
24        self.bulk_url.to_owned() + endpoint
25    }
26}
27
28impl Default for ZBUrlProvider {
29    fn default() -> Self {
30        ZBUrlProvider {
31            url: ApiBaseUrl::Default.as_str().to_string(),
32            bulk_url: crate::utility::BULK_URI.to_string(),
33        }
34    }
35}
36
37// Client offering methods for different API methods and functionalities
38pub struct ZeroBounce {
39    pub api_key: String,
40    pub base_url: String,
41    pub client: reqwest::blocking::Client,
42    pub url_provider: ZBUrlProvider,
43}
44
45// More method implementations of this class can be found throughout
46// the project.
47impl ZeroBounce {
48    /// Create a new ZeroBounce client instance with the default API URL.
49    /// 
50    /// # Arguments
51    /// * `api_key` - Your ZeroBounce API key
52    /// 
53    /// # Example
54    /// ```no_run
55    /// use zero_bounce::ZeroBounce;
56    /// 
57    /// let zb = ZeroBounce::new("your_api_key");
58    /// ```
59    pub fn new(api_key: &str) -> ZeroBounce {
60        Self::with_base_url(api_key, ApiBaseUrl::Default)
61    }
62
63    /// Create a new ZeroBounce client instance with a custom base URL.
64    /// 
65    /// # Arguments
66    /// * `api_key` - Your ZeroBounce API key
67    /// * `base_url` - Base URL. Can be:
68    ///   - `ApiBaseUrl::Default` - Uses the default API URL
69    ///   - `ApiBaseUrl::USA` - Uses the USA API URL
70    ///   - `ApiBaseUrl::EU` - Uses the EU API URL
71    ///   - `String` or `&str` - Uses a custom URL string
72    /// 
73    /// # Example
74    /// ```no_run
75    /// use zero_bounce::{ZeroBounce, ApiBaseUrl};
76    /// 
77    /// // Using enum
78    /// let zb = ZeroBounce::with_base_url("your_api_key", ApiBaseUrl::USA);
79    /// 
80    /// // Using custom string
81    /// let zb = ZeroBounce::with_base_url("your_api_key", "https://custom-api.example.com/v2/");
82    /// ```
83    pub fn with_base_url<T>(api_key: &str, base_url: T) -> ZeroBounce 
84    where
85        T: Into<String>,
86    {
87        let base_url_string = base_url.into();
88        
89        let mut url_provider = ZBUrlProvider::default();
90        url_provider.url = base_url_string.clone();
91        
92        ZeroBounce {
93            api_key: api_key.to_string(),
94            base_url: base_url_string,
95            client: reqwest::blocking::Client::default(),
96            url_provider,
97        }
98    }
99
100    fn generic_get_request<'a>(&'a self, url: String, mut query_args: HashMap<&'a str, &'a str>) -> ZBResult<String> {
101        // Automatically add api_key to query arguments
102        query_args.insert("api_key", self.api_key.as_str());
103        
104        let response = self.client.get(url).query(&query_args).send()?;
105
106        let response_ok = response.status().is_success();
107        let response_content = response.text()?;
108
109        // Debug: Print raw response to examine structure in debug mode
110        #[cfg(debug_assertions)]
111        {
112            eprintln!("Raw API response: {}", response_content);
113        }
114
115        if !response_ok {
116            return Err(ZBError::ExplicitError(response_content));
117        }
118
119        Ok(response_content)
120    }
121}