1use governor::{DefaultDirectRateLimiter, Quota, RateLimiter};
6use nonzero_ext::nonzero;
7use reqwest::Client;
8use serde::de::DeserializeOwned;
9
10use model::ip_response::{IpDefaultResponse, IpFullResponse};
11
12use crate::client::{AsyncIpApi, IpApi};
13use crate::error::IpApiError;
14
15#[cfg(feature = "blocking")]
16pub mod blocking;
17pub mod client;
18pub mod constant;
19pub mod error;
20pub mod model;
21pub mod request_handler;
22pub mod util;
23
24pub struct IpApiClient {
26 pub client: Client,
28 pub limiter: Option<DefaultDirectRateLimiter>,
30 pub api_key: Option<String>,
32}
33
34impl Default for IpApiClient {
35 fn default() -> Self {
36 Self::new()
37 }
38}
39
40impl IpApiClient {
41 pub fn new() -> Self {
43 Self {
44 client: Client::new(),
45 limiter: Some(RateLimiter::direct(Quota::per_minute(nonzero!(45u32)))),
46 api_key: None,
47 }
48 }
49
50 pub fn new_with_api_key(api_key: String) -> Self {
52 Self {
53 client: Client::new(),
54 limiter: None,
55 api_key: Some(api_key),
56 }
57 }
58}
59
60impl IpApi for IpApiClient {
61 fn get_api_key(&self) -> &Option<String> {
62 &self.api_key
63 }
64
65 fn get_rate_limiter(&self) -> &Option<DefaultDirectRateLimiter> {
66 &self.limiter
67 }
68}
69
70impl AsyncIpApi for IpApiClient {
71 async fn query_api_default(&self, ip: &str) -> Result<IpDefaultResponse, IpApiError> {
72 let request = util::requests::get_default_async_get_request(&ip.to_string(), self);
73 request_handler::perform_get_request::<IpDefaultResponse>(request, &self.limiter).await
74 }
75
76 async fn query_api_fully(&self, ip: &str) -> Result<IpFullResponse, IpApiError> {
77 let request = util::requests::get_async_request::<IpFullResponse>(&ip.to_string(), self);
78 request_handler::perform_get_request::<IpFullResponse>(request, &self.limiter).await
79 }
80
81 async fn query_api<T>(&self, ip: &str) -> Result<T, IpApiError>
82 where
83 T: DeserializeOwned,
84 {
85 let request = util::requests::get_async_request::<T>(&ip.to_string(), self);
86 request_handler::perform_get_request::<T>(request, &self.limiter).await
87 }
88
89 fn get_http_client(&self) -> &Client {
90 &self.client
91 }
92}