-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Blocking API (#9) * initial implementation of a blocking api * fixed clippy * fixed some things: - clippy - made the feature actually public - added tests - updated github ci * implemented blocking api with the blocking feature from reqwest - removed tokio as a dependency * made clippy happy + !!!breaking changes!!! * fixed github ci * updated documentations * renamed `as_number` to `asn` (#12) * moved tests into separate directory + added some more (#14) * updated version to `2.0.0`
- Loading branch information
1 parent
4892828
commit 0c4fcbe
Showing
22 changed files
with
607 additions
and
188 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[package] | ||
name = "ip-api4rs" | ||
version = "1.0.0" | ||
version = "2.0.0" | ||
authors = ["Timon Klinkert <[email protected]>"] | ||
description = "A Rust library for the ip-api.com API." | ||
license = "Apache-2.0" | ||
|
@@ -11,14 +11,19 @@ readme = "README.md" | |
edition = "2021" | ||
rust-version = "1.73.0" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
[features] | ||
blocking = ["reqwest/blocking"] | ||
|
||
[dev-dependencies] | ||
# Async runtime | ||
tokio = { version = "1.33.0", features = ["rt", "macros", "rt-multi-thread"] } | ||
|
||
[dependencies] | ||
#Async traits | ||
async-trait = "0.1.74" | ||
|
||
# HTTP client | ||
reqwest = { version = "0.11", features = ["json"] } | ||
reqwest = { version = "0.11", features = ["json", "blocking"] } | ||
|
||
# Ratelimiting | ||
governor = "0.6.0" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,4 @@ edition = "2021" | |
max_width = 120 | ||
newline_style = "Unix" | ||
use_small_heuristics = "Off" | ||
hard_tabs = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
use governor::{DefaultDirectRateLimiter, Quota, RateLimiter}; | ||
use nonzero_ext::nonzero; | ||
use reqwest::blocking::Client; | ||
use serde::de::DeserializeOwned; | ||
|
||
use crate::client::{BlockingIpApi, IpApi}; | ||
use crate::error::IpApiError; | ||
use crate::model::ip_response::{IpDefaultResponse, IpFullResponse}; | ||
use crate::{request_handler, util}; | ||
|
||
/// A client for the ip-api.com API that blocks the current thread. | ||
pub struct BlockingIpApiClient { | ||
/// The client to use for the requests. | ||
pub client: Client, | ||
/// The rate limiter to use for the requests. | ||
pub limiter: Option<DefaultDirectRateLimiter>, | ||
/// The API key to use for the requests. | ||
pub api_key: Option<String>, | ||
} | ||
|
||
impl Default for BlockingIpApiClient { | ||
fn default() -> Self { | ||
Self::new() | ||
} | ||
} | ||
|
||
impl BlockingIpApiClient { | ||
/// Creates a new BlockingIpApiClient with no API key. | ||
pub fn new() -> Self { | ||
Self { | ||
client: Client::new(), | ||
limiter: Some(RateLimiter::direct(Quota::per_minute(nonzero!(45u32)))), | ||
api_key: None, | ||
} | ||
} | ||
|
||
/// Creates a new BlockingIpApiClient with an API key. | ||
pub fn new_with_api_key(api_key: String) -> Self { | ||
Self { | ||
client: Client::new(), | ||
limiter: None, | ||
api_key: Some(api_key), | ||
} | ||
} | ||
} | ||
|
||
impl IpApi for BlockingIpApiClient { | ||
fn get_api_key(&self) -> &Option<String> { | ||
&self.api_key | ||
} | ||
|
||
fn get_rate_limiter(&self) -> &Option<DefaultDirectRateLimiter> { | ||
&self.limiter | ||
} | ||
} | ||
|
||
impl BlockingIpApi for BlockingIpApiClient { | ||
fn query_api_default(&self, ip: &str) -> Result<IpDefaultResponse, IpApiError> { | ||
let request = util::requests::get_default_blocking_get_request(&ip.to_string(), self); | ||
request_handler::perform_blocking_get_request::<IpDefaultResponse>(request, &self.limiter) | ||
} | ||
|
||
fn query_api_fully(&self, ip: &str) -> Result<IpFullResponse, IpApiError> { | ||
let request = util::requests::get_blocking_get_request::<IpFullResponse>(&ip.to_string(), self); | ||
request_handler::perform_blocking_get_request::<IpFullResponse>(request, &self.limiter) | ||
} | ||
|
||
fn query_api<T>(&self, ip: &str) -> Result<T, IpApiError> | ||
where | ||
T: DeserializeOwned, | ||
{ | ||
let request = util::requests::get_blocking_get_request::<T>(&ip.to_string(), self); | ||
request_handler::perform_blocking_get_request::<T>(request, &self.limiter) | ||
} | ||
|
||
fn get_http_client(&self) -> &Client { | ||
&self.client | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod client; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
use async_trait::async_trait; | ||
use governor::DefaultDirectRateLimiter; | ||
use reqwest::blocking; | ||
use serde::de::DeserializeOwned; | ||
|
||
use crate::error::IpApiError; | ||
use crate::model::ip_response::{IpDefaultResponse, IpFullResponse}; | ||
|
||
/// The main client for the ip-api.com API. | ||
pub trait IpApi { | ||
/// Gets the optional API key. | ||
/// | ||
/// # Returns | ||
/// * `Option<String>` - The optional API key. | ||
fn get_api_key(&self) -> &Option<String>; | ||
|
||
/// Gets the rate limiter. | ||
/// | ||
/// # Returns | ||
/// * `&DefaultDirectRateLimiter` - The rate limiter. | ||
fn get_rate_limiter(&self) -> &Option<DefaultDirectRateLimiter>; | ||
} | ||
|
||
/// The blocking client for the ip-api.com API. | ||
#[cfg(feature = "blocking")] | ||
pub trait BlockingIpApi: IpApi { | ||
/// Queries the API with the default fields. | ||
/// | ||
/// # Arguments | ||
/// * `ip` - The IP address to query. | ||
/// | ||
/// # Returns | ||
/// * `IpDefaultResponse` - The response from the API. | ||
fn query_api_default(&self, ip: &str) -> Result<IpDefaultResponse, IpApiError>; | ||
|
||
/// Queries the API with all fields. | ||
/// | ||
/// # Arguments | ||
/// * `ip` - The IP address to query. | ||
/// | ||
/// # Returns | ||
/// * `IpFullResponse` - The response from the API. | ||
fn query_api_fully(&self, ip: &str) -> Result<IpFullResponse, IpApiError>; | ||
|
||
/// Queries the API with a custom struct. | ||
/// | ||
/// # Arguments | ||
/// * `ip` - The IP address to query. | ||
/// * `T` - The custom struct to deserialize the response into. | ||
/// | ||
/// # Returns | ||
/// * `T` - The response from the API. | ||
fn query_api<T>(&self, ip: &str) -> Result<T, IpApiError> | ||
where | ||
T: DeserializeOwned; | ||
|
||
/// Gets you the blocking http client. | ||
/// | ||
/// # Returns | ||
/// * `&reqwest::blocking::Client` - The blocking http client. | ||
fn get_http_client(&self) -> &blocking::Client; | ||
} | ||
|
||
/// The async client for the ip-api.com API. | ||
#[async_trait] | ||
pub trait AsyncIpApi: IpApi { | ||
/// Queries the API with the default fields. | ||
/// | ||
/// # Arguments | ||
/// * `ip` - The IP address to query. | ||
/// | ||
/// # Returns | ||
/// * `IpDefaultResponse` - The response from the API. | ||
async fn query_api_default(&self, ip: &str) -> Result<IpDefaultResponse, IpApiError>; | ||
|
||
/// Queries the API with all fields. | ||
/// | ||
/// # Arguments | ||
/// * `ip` - The IP address to query. | ||
/// | ||
/// # Returns | ||
/// * `IpFullResponse` - The response from the API. | ||
async fn query_api_fully(&self, ip: &str) -> Result<IpFullResponse, IpApiError>; | ||
|
||
/// Queries the API with a custom struct. | ||
/// | ||
/// # Arguments | ||
/// * `ip` - The IP address to query. | ||
/// * `T` - The custom struct to deserialize the response into. | ||
/// | ||
/// # Returns | ||
/// * `T` - The response from the API. | ||
async fn query_api<T>(&self, ip: &str) -> Result<T, IpApiError> | ||
where | ||
T: DeserializeOwned; | ||
/// Gets you the async http client. | ||
/// | ||
/// # Returns | ||
/// * `&reqwest::Client` - The async http client. | ||
fn get_http_client(&self) -> &reqwest::Client; | ||
} |
Oops, something went wrong.