1mod checker;
2use crate::checker::Checker;
3mod structs;
4mod misc;
5
6use crate::structs::{IpInfo, ASN};
7use tokio::sync::OnceCell;
8
9use std::{net::IpAddr, str::FromStr};
10use reqwest_middleware::{Result, ClientWithMiddleware};
11use ipnet::IpNet;
12
13static CHECKER: OnceCell<Checker> = OnceCell::const_new();
14
15async fn get_checker() -> &'static Checker {
16 CHECKER.get_or_init(|| async {
17 let mut checker = Checker::new();
18 checker.init().await;
19 checker
20 }).await
21}
22
23pub async fn check(address: IpAddr) -> Option<IpInfo> {
24 let mut checker = Checker::new();
25 checker.init().await;
26 checker.search(&address).await
27}
28
29#[cfg(test)]
30mod tests {
31 use super::*;
32
33 async fn verify_ip_data(ip: &IpAddr, real: &IpInfo) -> Result<()> {
34 let checker = get_checker().await;
35
36 let Some(found) = checker.search(ip).await else {
38 panic!("Not found");
39 };
40 assert_eq!(found, *real);
41 Ok(())
42 }
43
44 #[tokio::test]
45 async fn check_ipv4() {
46 let cfn_ip = IpAddr::from_str("1.1.1.1").unwrap();
48 let cfn_net = IpNet::from_str("1.1.1.0/24").unwrap();
49
50 let real = IpInfo {
51 ip: Some(cfn_ip),
52 net: cfn_net,
53 asn: ASN {
54 id: 13335,
55 name: "CLOUDFLARENET,".to_string(),
56 cc: "US".to_string()
57 }
58 };
59
60 let _ = verify_ip_data(&cfn_ip, &real).await;
61 }
62
63 #[tokio::test]
64 async fn check_ipv6() {
65 let cfn_ip = IpAddr::from_str("2001:678:19c::1").unwrap();
67 let cfn_net = IpNet::from_str("2001:678:19c::/48").unwrap();
68
69 let real = IpInfo {
70 ip: Some(cfn_ip),
71 net: cfn_net,
72 asn: ASN {
73 id: 13335,
74 name: "CLOUDFLARENET,".to_string(),
75 cc: "US".to_string()
76 }
77 };
78
79 let _ = verify_ip_data(&cfn_ip, &real).await;
80 }
81}