nullnet_libipinfo/
ip_info.rs

1use maxminddb::geoip2::{Asn, City};
2
3#[derive(Debug, PartialEq, Default)]
4/// Struct to hold information about an IP address.
5pub struct IpInfo {
6    pub country: Option<String>,
7    pub asn: Option<String>,
8    pub org: Option<String>,
9    pub continent_code: Option<String>,
10    pub city: Option<String>,
11    pub region: Option<String>,
12    pub postal: Option<String>,
13    pub timezone: Option<String>,
14}
15
16impl IpInfo {
17    pub(crate) fn from_mmdb(city: Option<&City>, asn: Option<&Asn>) -> Self {
18        Self {
19            country: city
20                .as_ref()
21                .and_then(|city| city.country.as_ref().and_then(|country| country.iso_code))
22                .map(std::string::ToString::to_string),
23            asn: asn.as_ref().and_then(|asn| {
24                asn.autonomous_system_number
25                    .map(|asn_number| asn_number.to_string())
26            }),
27            org: asn.as_ref().and_then(|asn| {
28                asn.autonomous_system_organization
29                    .map(std::string::ToString::to_string)
30            }),
31            continent_code: city
32                .as_ref()
33                .and_then(|city| city.continent.as_ref().and_then(|continent| continent.code))
34                .map(std::string::ToString::to_string),
35            city: city
36                .as_ref()
37                .and_then(|city| {
38                    city.city
39                        .as_ref()
40                        .and_then(|city| city.names.as_ref().and_then(|names| names.get("en")))
41                })
42                .map(std::string::ToString::to_string),
43            region: city
44                .as_ref()
45                .and_then(|city| {
46                    city.subdivisions
47                        .as_ref()
48                        .and_then(|subdivisions| subdivisions.first())
49                })
50                .and_then(|subdivision| {
51                    subdivision.names.as_ref().and_then(|names| names.get("en"))
52                })
53                .map(std::string::ToString::to_string),
54            postal: city
55                .as_ref()
56                .and_then(|city| city.postal.as_ref().and_then(|postal| postal.code))
57                .map(std::string::ToString::to_string),
58            timezone: city
59                .as_ref()
60                .and_then(|city| {
61                    city.location
62                        .as_ref()
63                        .and_then(|location| location.time_zone)
64                })
65                .map(std::string::ToString::to_string),
66        }
67    }
68}