Skip to main content

xdb_parse/
ip.rs

1use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
2use std::str::FromStr;
3
4use crate::error::XdbError;
5
6/// Types that can be converted to an [`IpAddr`] for IP lookup.
7///
8/// Implemented for common IP representations so [`crate::search_ip`] accepts
9/// `&str`, `String`, `u32`, `u128`, `IpAddr`, `Ipv4Addr`, and `Ipv6Addr`.
10pub trait IntoIpAddr {
11    fn into_ip_addr(self) -> Result<IpAddr, XdbError>;
12}
13
14impl IntoIpAddr for IpAddr {
15    fn into_ip_addr(self) -> Result<IpAddr, XdbError> {
16        Ok(self)
17    }
18}
19
20impl IntoIpAddr for Ipv4Addr {
21    fn into_ip_addr(self) -> Result<IpAddr, XdbError> {
22        Ok(IpAddr::V4(self))
23    }
24}
25
26impl IntoIpAddr for Ipv6Addr {
27    fn into_ip_addr(self) -> Result<IpAddr, XdbError> {
28        Ok(IpAddr::V6(self))
29    }
30}
31
32impl IntoIpAddr for u32 {
33    fn into_ip_addr(self) -> Result<IpAddr, XdbError> {
34        Ok(IpAddr::V4(Ipv4Addr::from(self)))
35    }
36}
37
38impl IntoIpAddr for u128 {
39    fn into_ip_addr(self) -> Result<IpAddr, XdbError> {
40        Ok(IpAddr::V6(Ipv6Addr::from(self)))
41    }
42}
43
44impl IntoIpAddr for &str {
45    fn into_ip_addr(self) -> Result<IpAddr, XdbError> {
46        parse_ip(self)
47    }
48}
49
50impl IntoIpAddr for String {
51    fn into_ip_addr(self) -> Result<IpAddr, XdbError> {
52        parse_ip(&self)
53    }
54}
55
56impl IntoIpAddr for &String {
57    fn into_ip_addr(self) -> Result<IpAddr, XdbError> {
58        parse_ip(self)
59    }
60}
61
62pub(crate) fn parse_ip(ip: &str) -> Result<IpAddr, XdbError> {
63    if ip.contains('.') || ip.contains(':') {
64        return Ok(IpAddr::from_str(ip)?);
65    }
66    if let Ok(num) = ip.parse::<u32>() {
67        return Ok(IpAddr::V4(Ipv4Addr::from(num)));
68    }
69    if let Ok(num) = ip.parse::<u128>() {
70        return Ok(IpAddr::V6(Ipv6Addr::from(num)));
71    }
72    Err(XdbError::InvalidIP("invalid IP or number".into()))
73}