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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
use crate::Ipv4Addr;
use crate::Ipv4Address;
use core::fmt;
use core::hash;

/// Describe the internal data structure behavior of `SocketAddrV4`.
///
/// You can implement this trait by yourself or use ffi for specific Platform.
pub trait SocketAddressV4: Clone + Copy {
    /// Ipv4Address inner type.
    type IpAddress: Ipv4Address;

    /// Creates a new IPv4 address from ip address and port
    ///
    /// The result will represent the Socket address ip:port.
    fn new(ip: Ipv4Addr<Self::IpAddress>, port: u16) -> Self;

    /// Got ip address.
    fn ip(&self) -> &Ipv4Addr<Self::IpAddress>;

    /// Set ip address.
    fn set_ip(&mut self, ip: Ipv4Addr<Self::IpAddress>);
    /// Got port.
    fn port(&self) -> u16;

    /// Set port.
    fn set_port(&mut self, port: u16);
}

/// An IPv4 socket address.
///
/// IPv4 socket addresses consist of an [IPv4 address] and a 16-bit port number, as
/// stated in [IETF RFC 793].
///
/// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses.
///
/// The size of a `SocketAddrV4` struct may vary depending on the target operating
/// system.
///
/// [IETF RFC 793]: https://tools.ietf.org/html/rfc793
/// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html
/// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
///
/// # Examples
///
/// ```
/// use std::net::{Ipv4Addr, SocketAddrV4};
///
/// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
///
/// assert_eq!("127.0.0.1:8080".parse(), Ok(socket));
/// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1));
/// assert_eq!(socket.port(), 8080);
/// ```
pub struct SocketAddrV4<SA4: SocketAddressV4> {
    inner: SA4,
}

impl<SA4: SocketAddressV4> SocketAddrV4<SA4> {
    /// Creates a new socket address from an [IPv4 address] and a port number.
    ///
    /// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html
    ///
    /// # Examples
    ///
    /// ```
    /// use std::net::{SocketAddrV4, Ipv4Addr};
    ///
    /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
    /// ```
    pub fn new(ip: Ipv4Addr<SA4::IpAddress>, port: u16) -> SocketAddrV4<SA4> {
        SocketAddrV4 {
            inner: SA4::new(ip, port),
        }
    }

    /// Returns the IP address associated with this socket address.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::net::{SocketAddrV4, Ipv4Addr};
    ///
    /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
    /// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1));
    /// ```
    pub fn ip(&self) -> &Ipv4Addr<SA4::IpAddress> {
        self.inner.ip()
    }

    /// Changes the IP address associated with this socket address.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::net::{SocketAddrV4, Ipv4Addr};
    ///
    /// let mut socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
    /// socket.set_ip(Ipv4Addr::new(192, 168, 0, 1));
    /// assert_eq!(socket.ip(), &Ipv4Addr::new(192, 168, 0, 1));
    /// ```
    pub fn set_ip(&mut self, new_ip: Ipv4Addr<SA4::IpAddress>) {
        self.inner.set_ip(new_ip)
    }

    /// Returns the port number associated with this socket address.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::net::{SocketAddrV4, Ipv4Addr};
    ///
    /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
    /// assert_eq!(socket.port(), 8080);
    /// ```
    pub fn port(&self) -> u16 {
        self.inner.port()
    }

    /// Changes the port number associated with this socket address.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::net::{SocketAddrV4, Ipv4Addr};
    ///
    /// let mut socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
    /// socket.set_port(4242);
    /// assert_eq!(socket.port(), 4242);
    /// ```
    pub fn set_port(&mut self, new_port: u16) {
        self.inner.set_port(new_port)
    }
}

impl<SA4: SocketAddressV4> Clone for SocketAddrV4<SA4> {
    fn clone(&self) -> SocketAddrV4<SA4> {
        SocketAddrV4 {
            inner: self.inner.clone(),
        }
    }
}

impl<SA4: SocketAddressV4> Copy for SocketAddrV4<SA4> {}

impl<SA4: SocketAddressV4> fmt::Display for SocketAddrV4<SA4> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}:{}", self.ip(), self.port())
    }
}

impl<SA4: SocketAddressV4> fmt::Debug for SocketAddrV4<SA4> {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Display::fmt(self, fmt)
    }
}

impl<SA4: SocketAddressV4> Eq for SocketAddrV4<SA4> {}

impl<SA4: SocketAddressV4> PartialEq for SocketAddrV4<SA4> {
    fn eq(&self, other: &SocketAddrV4<SA4>) -> bool {
        let s_ip = self.ip();
        let o_ip = other.ip();

        let s_port = self.port();
        let o_port = other.port();
        (s_ip, s_port).eq(&(o_ip, o_port))
    }
}

impl<SA4: SocketAddressV4> hash::Hash for SocketAddrV4<SA4> {
    fn hash<H: hash::Hasher>(&self, s: &mut H) {
        let ip = self.ip();
        let port = self.port();
        (ip.octets(), port).hash(s)
    }
}