ip_api4rs/blocking/
client.rs

1use governor::{DefaultDirectRateLimiter, Quota, RateLimiter};
2use nonzero_ext::nonzero;
3use reqwest::blocking::Client;
4use serde::de::DeserializeOwned;
5
6use crate::client::{BlockingIpApi, IpApi};
7use crate::error::IpApiError;
8use crate::model::ip_response::{IpDefaultResponse, IpFullResponse};
9use crate::{request_handler, util};
10
11/// A client for the ip-api.com API that blocks the current thread.
12pub struct BlockingIpApiClient {
13    /// The client to use for the requests.
14    pub client: Client,
15    /// The rate limiter to use for the requests.
16    pub limiter: Option<DefaultDirectRateLimiter>,
17    /// The API key to use for the requests.
18    pub api_key: Option<String>,
19}
20
21impl Default for BlockingIpApiClient {
22    fn default() -> Self {
23        Self::new()
24    }
25}
26
27impl BlockingIpApiClient {
28    /// Creates a new BlockingIpApiClient with no API key.
29    pub fn new() -> Self {
30        Self {
31            client: Client::new(),
32            limiter: Some(RateLimiter::direct(Quota::per_minute(nonzero!(45u32)))),
33            api_key: None,
34        }
35    }
36
37    /// Creates a new BlockingIpApiClient with an API key.
38    pub fn new_with_api_key(api_key: String) -> Self {
39        Self {
40            client: Client::new(),
41            limiter: None,
42            api_key: Some(api_key),
43        }
44    }
45}
46
47impl IpApi for BlockingIpApiClient {
48    fn get_api_key(&self) -> &Option<String> {
49        &self.api_key
50    }
51
52    fn get_rate_limiter(&self) -> &Option<DefaultDirectRateLimiter> {
53        &self.limiter
54    }
55}
56
57impl BlockingIpApi for BlockingIpApiClient {
58    fn query_api_default(&self, ip: &str) -> Result<IpDefaultResponse, IpApiError> {
59        let request = util::requests::get_default_blocking_get_request(&ip.to_string(), self);
60        request_handler::perform_blocking_get_request::<IpDefaultResponse>(request, &self.limiter)
61    }
62
63    fn query_api_fully(&self, ip: &str) -> Result<IpFullResponse, IpApiError> {
64        let request = util::requests::get_blocking_get_request::<IpFullResponse>(&ip.to_string(), self);
65        request_handler::perform_blocking_get_request::<IpFullResponse>(request, &self.limiter)
66    }
67
68    fn query_api<T>(&self, ip: &str) -> Result<T, IpApiError>
69    where
70        T: DeserializeOwned,
71    {
72        let request = util::requests::get_blocking_get_request::<T>(&ip.to_string(), self);
73        request_handler::perform_blocking_get_request::<T>(request, &self.limiter)
74    }
75
76    fn get_http_client(&self) -> &Client {
77        &self.client
78    }
79}