use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
use serde::{ Deserialize, Serialize };
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IpInfo {
pub country: Option<String>,
pub province: Option<String>,
pub city: Option<String>,
pub isp: Option<String>,
pub addr: Option<String>,
}
impl BpiClient {
pub async fn clientinfo_ip(&self, ip: Option<&str>) -> Result<BpiResponse<IpInfo>, BpiError> {
let mut req = self.get(
"https://api.live.bilibili.com/ip_service/v1/ip_service/get_ip_addr"
);
if let Some(ip) = ip {
req = req.query(&[("ip", ip)]);
}
req.send_bpi("查询 IP 地址归属地").await
}
}
#[cfg(test)]
mod tests {
use super::*;
const TEST_IP: &str = "8.8.8.8";
#[tokio::test]
async fn test_clientinfo_ip() -> Result<(), Box<BpiError>> {
let bpi = BpiClient::new();
let resp = bpi.clientinfo_ip(Some(TEST_IP)).await?;
if resp.code == 0 {
if let Some(data) = resp.data {
tracing::info!(
"IP 地址: {}, 省份: {:?}, 城市: {:?}, ISP: {:?}",
data.addr.unwrap_or_default(),
data.province,
data.city,
data.isp
);
}
} else {
tracing::error!("请求失败: code={}, message={}", resp.code, resp.message);
}
Ok(())
}
}