ip_api4rs/util/
requests.rs

1//! A utility module for building requests to the API.
2
3#[cfg(feature = "blocking")]
4use crate::client::BlockingIpApi;
5use crate::client::{AsyncIpApi, IpApi};
6#[cfg(feature = "blocking")]
7use reqwest::blocking;
8use reqwest::header::HeaderMap;
9use reqwest::{Client, RequestBuilder};
10use serde::de::DeserializeOwned;
11
12use crate::model::ip_response::IpDefaultResponse;
13use crate::util::urls::build_url_from_struct;
14
15/// Builds the request for a default response.
16///
17/// # Arguments
18/// * `query` - The IP address to query for.
19/// * `client` - The `AsyncIpApi` to use for the request.
20///
21/// # Returns
22/// A `RequestBuilder` for the request.
23pub fn get_default_async_get_request(query: &String, client: &impl AsyncIpApi) -> RequestBuilder {
24    get_async_request::<IpDefaultResponse>(query, client)
25}
26
27/// Builds the blocking request for a default response.
28///
29/// # Arguments
30/// * `query` - The IP address to query for.
31/// * `client` - The `BlockingIpApi` to use for the request.
32///
33/// # Returns
34/// A `blocking::RequestBuilder` for the request.
35#[cfg(feature = "blocking")]
36pub fn get_default_blocking_get_request(query: &String, client: &impl BlockingIpApi) -> blocking::RequestBuilder {
37    get_blocking_get_request::<IpDefaultResponse>(query, client)
38}
39
40/// Builds the async request for a custom response.
41/// The given struct must implement `DeserializeOwned`.
42///
43/// # Arguments
44/// * `query` - The IP address to query for.
45/// * `client` - The `AsyncIpApi` to use for the request.
46///
47/// # Returns
48/// A `RequestBuilder` for the request.
49pub fn get_async_request<T>(query: &String, client: &impl AsyncIpApi) -> RequestBuilder
50where
51    T: DeserializeOwned,
52{
53    let url = get_url::<T>(query, client);
54    match client.get_api_key() {
55        Some(_) => build_https_get_request(&url, client.get_api_key().as_ref().unwrap(), client.get_http_client()),
56        None => build_http_get_request(&url, client.get_http_client()),
57    }
58}
59
60/// Builds the blocking request for a custom response.
61/// The given struct must implement `DeserializeOwned`.
62///
63/// # Arguments
64/// * `query` - The IP address to query for.
65/// * `client` - The `BlockingIpApi` to use for the request.
66///
67/// # Returns
68/// A `blocking::RequestBuilder` for the request.
69#[cfg(feature = "blocking")]
70pub fn get_blocking_get_request<T>(query: &String, client: &impl BlockingIpApi) -> blocking::RequestBuilder
71where
72    T: DeserializeOwned,
73{
74    let url = get_url::<T>(query, client);
75    match client.get_api_key() {
76        Some(_) => {
77            build_blocking_https_get_request(&url, client.get_api_key().as_ref().unwrap(), client.get_http_client())
78        }
79        None => build_blocking_http_get_request(&url, client.get_http_client()),
80    }
81}
82
83/// Builds a https request.
84///
85/// # Arguments
86/// * `url` - The url to build the request for.
87/// * `api_key` - The API key to use for the request.
88/// * `client` - The `Client` to use for the request.
89///
90/// # Returns
91/// A `RequestBuilder` for the request.
92fn build_https_get_request(url: &String, api_key: &str, client: &Client) -> RequestBuilder {
93    client.get(url).headers(build_https_header(api_key))
94}
95
96/// Builds a blocking https request.
97///
98/// # Arguments
99/// * `url` - The url to build the request for.
100/// * `api_key` - The API key to use for the request.
101/// * `client` - The `blocking::Client` to use for the request.
102///
103/// # Returns
104/// A `RequestBuilder` for the request.
105#[cfg(feature = "blocking")]
106fn build_blocking_https_get_request(
107    url: &String,
108    api_key: &str,
109    client: &blocking::Client,
110) -> blocking::RequestBuilder {
111    client.get(url).headers(build_https_header(api_key))
112}
113
114/// Builds a http request.
115///
116/// # Arguments
117/// * `url` - The url to build the request for.
118/// * `client` - The `Client` to use for the request.
119///
120/// # Returns
121/// A `RequestBuilder` for the request.
122fn build_http_get_request(url: &String, client: &Client) -> RequestBuilder {
123    client.get(url).headers(build_http_header())
124}
125
126/// Builds a blocking http request.
127///
128/// # Arguments
129/// * `url` - The url to build the request for.
130/// * `client` - The `blocking::Client` to use for the request.
131///
132/// # Returns
133/// A `RequestBuilder` for the request.
134#[cfg(feature = "blocking")]
135fn build_blocking_http_get_request(url: &String, client: &blocking::Client) -> blocking::RequestBuilder {
136    client.get(url).headers(build_http_header())
137}
138
139/// Builds the url for a request.
140///
141/// # Arguments
142/// * `query` - The IP address to query for.
143/// * `client` - The `IpApiClient` to use for the request.
144///
145/// # Returns
146/// A `String` containing the url for the request.
147fn get_url<T>(query: &String, client: &impl IpApi) -> String
148where
149    T: DeserializeOwned,
150{
151    match client.get_api_key() {
152        Some(_) => build_url_from_struct::<T>(true, query),
153        None => build_url_from_struct::<T>(false, query),
154    }
155}
156
157/// Builds an header that set the `Accept` and `User-Agent` fields.
158///
159/// # Returns
160/// A `HeaderMap` containing the headers.
161fn build_http_header() -> HeaderMap {
162    let mut headers = HeaderMap::new();
163    headers.insert("Accept", "application/json".parse().unwrap());
164    //headers.insert("User-Agent", format!("ip-api-rust/{}", env!("CARGO_PKG_VERSION")).parse().unwrap());
165    headers
166}
167
168/// Builds an header that extends the header from `build_http_header`.
169/// Adds the api_key to the header.
170///
171/// # Arguments
172/// * `api_key` - The API key to use for the request.
173///
174/// # Returns
175/// A `HeaderMap` containing the headers.
176fn build_https_header(api_key: &str) -> HeaderMap {
177    let mut headers = build_http_header();
178    headers.insert("Authorization: Bearer", api_key.parse().unwrap());
179    headers
180}