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