geo_ip/
lib.rs

1use reqwest::redirect::Policy;
2use reqwest::StatusCode;
3use serde::Deserialize;
4use serde_json::Value;
5/// Specify an argument with form IPv4 address, which is `Option<String>`
6/// > 1. If the argument is None, acquire the information about the IP of the current location
7/// >
8/// > 2. If the argument is String, acquire the information about the specified IP address
9/// 
10/// # Examples
11/// ```
12/// # #[tokio::main]
13/// # async fn main()->anyhow::Result<()> {
14/// #  use serde_json::Value;
15///    let r = geo_ip::geo_ip::<Value>(None).await?;
16///    assert!(r.get("code").unwrap().as_str().unwrap() == "Success");
17/// #   Ok(())
18/// #  }
19/// ```
20pub async fn geo_ip<T: Deserialize<'static>>(ipv4: Option<String>) -> anyhow::Result<T> {
21    let client = reqwest::Client::builder()
22        .timeout(std::time::Duration::from_secs(10))
23        .redirect(Policy::none())
24        .build()?;
25    let api = if let Some(addr) = ipv4 {
26        format!("https://qifu-api.baidubce.com/ip/geo/v1/district?ip={addr}")
27    } else {
28        "https://qifu-api.baidubce.com/ip/local/geo/v1/district".to_owned()
29    };
30    let res = client
31        .get(api)
32        .header(
33            "User-Agent",
34            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/116.0",
35        )
36        .send()
37        .await?;
38    if res.status() == StatusCode::OK {
39        let body = res.json::<Value>().await?;
40        return Ok(T::deserialize(body)?);
41    } else {
42        return Err(anyhow::anyhow!("http response is not ok"));
43    }
44}