1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
use crate::error::{Error, Result};
use std::net::{IpAddr, Ipv4Addr};
use std::net::{SocketAddr, SocketAddrV4};

/// Helper trait to convert things into IPv4 addresses.
#[allow(clippy::wrong_self_convention)]
pub trait IntoAddress {
    /// Convert the type to an `Ipv4Addr`.
    fn into_address(&self) -> Result<IpAddr>;
}

impl IntoAddress for u32 {
    fn into_address(&self) -> Result<IpAddr> {
        Ok(IpAddr::V4(Ipv4Addr::new(
            ((*self) & 0xff) as u8,
            ((*self >> 8) & 0xff) as u8,
            ((*self >> 16) & 0xff) as u8,
            ((*self >> 24) & 0xff) as u8,
        )))
    }
}
impl IntoAddress for u8 {
    fn into_address(&self) -> Result<IpAddr> {
        let prefix = *self;
        let mask = if prefix == 0 {
            0
        } else {
            (!0u32) << (32 - prefix)
        };
        Ok(Ipv4Addr::from(mask).into())
    }
}

impl IntoAddress for i32 {
    fn into_address(&self) -> Result<IpAddr> {
        (*self as u32).into_address()
    }
}

impl IntoAddress for (u8, u8, u8, u8) {
    fn into_address(&self) -> Result<IpAddr> {
        Ok(IpAddr::V4(Ipv4Addr::new(self.0, self.1, self.2, self.3)))
    }
}

impl IntoAddress for str {
    fn into_address(&self) -> Result<IpAddr> {
        self.parse().map_err(|_| Error::InvalidAddress)
    }
}

impl<'a> IntoAddress for &'a str {
    fn into_address(&self) -> Result<IpAddr> {
        (*self).into_address()
    }
}

impl IntoAddress for String {
    fn into_address(&self) -> Result<IpAddr> {
        self.as_str().into_address()
    }
}

impl<'a> IntoAddress for &'a String {
    fn into_address(&self) -> Result<IpAddr> {
        self.as_str().into_address()
    }
}

impl IntoAddress for Ipv4Addr {
    fn into_address(&self) -> Result<IpAddr> {
        Ok(IpAddr::V4(*self))
    }
}

impl<'a> IntoAddress for &'a Ipv4Addr {
    fn into_address(&self) -> Result<IpAddr> {
        (*self).into_address()
    }
}

impl IntoAddress for IpAddr {
    fn into_address(&self) -> Result<IpAddr> {
        match self {
            IpAddr::V4(value) => Ok(IpAddr::V4(*value)),

            IpAddr::V6(_) => unimplemented!(),
        }
    }
}

impl<'a> IntoAddress for &'a IpAddr {
    fn into_address(&self) -> Result<IpAddr> {
        (*self).into_address()
    }
}

impl IntoAddress for SocketAddrV4 {
    fn into_address(&self) -> Result<IpAddr> {
        Ok(IpAddr::V4(*self.ip()))
    }
}

impl<'a> IntoAddress for &'a SocketAddrV4 {
    fn into_address(&self) -> Result<IpAddr> {
        (*self).into_address()
    }
}

impl IntoAddress for SocketAddr {
    fn into_address(&self) -> Result<IpAddr> {
        match self {
            SocketAddr::V4(value) => Ok(IpAddr::V4(*value.ip())),

            SocketAddr::V6(_) => unimplemented!(),
        }
    }
}

impl<'a> IntoAddress for &'a SocketAddr {
    fn into_address(&self) -> Result<IpAddr> {
        (*self).into_address()
    }
}
#[allow(dead_code)]
pub fn format_mac_address(mac: &[u8; 6]) -> String {
    mac.iter()
        .map(|b| format!("{:02X}", b))
        .collect::<Vec<_>>()
        .join("")
}