1use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
2use std::str::FromStr;
3
4use crate::error::XdbError;
5
6pub 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}