about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-02-11 18:44:52 +0000
committerbors <bors@rust-lang.org>2016-02-11 18:44:52 +0000
commit7342dd8727644b5e23c05be9930fd499f507f0d3 (patch)
tree5ac318779ba003e6bb0481dc005a96e53dca7c79
parentaa1dc0975a43e224386ec0ed1bb7ae09cfd0dd7e (diff)
parent3de820ee7912f46761ca4f0c50f67164aaa5f42f (diff)
downloadrust-7342dd8727644b5e23c05be9930fd499f507f0d3.tar.gz
rust-7342dd8727644b5e23c05be9930fd499f507f0d3.zip
Auto merge of #31083 - SimonSapin:set_port, r=alexcrichton
As demonstrated in the `resolve_socket_addr` change, this is less awkward than re-creating a new address from the other parts.

If this is to be accepted, pleas open a tracking issue (I can’t set the appropriate tags) and I’ll update the PR with the tracking issue number.
-rw-r--r--src/libstd/net/addr.rs130
1 files changed, 120 insertions, 10 deletions
diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs
index 751b9b1802c..89c51c70843 100644
--- a/src/libstd/net/addr.rs
+++ b/src/libstd/net/addr.rs
@@ -67,6 +67,17 @@ impl SocketAddr {
         }
     }
 
+    /// Change the IP address associated with this socket address.
+    #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")]
+    pub fn set_ip(&mut self, new_ip: IpAddr) {
+        // `match (*self, new_ip)` would have us mutate a copy of self only to throw it away.
+        match (self, new_ip) {
+            (&mut SocketAddr::V4(ref mut a), IpAddr::V4(new_ip)) => a.set_ip(new_ip),
+            (&mut SocketAddr::V6(ref mut a), IpAddr::V6(new_ip)) => a.set_ip(new_ip),
+            (self_, new_ip) => *self_ = Self::new(new_ip, self_.port()),
+        }
+    }
+
     /// Returns the port number associated with this socket address.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn port(&self) -> u16 {
@@ -75,6 +86,15 @@ impl SocketAddr {
             SocketAddr::V6(ref a) => a.port(),
         }
     }
+
+    /// Change the port number associated with this socket address.
+    #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")]
+    pub fn set_port(&mut self, new_port: u16) {
+        match *self {
+            SocketAddr::V4(ref mut a) => a.set_port(new_port),
+            SocketAddr::V6(ref mut a) => a.set_port(new_port),
+        }
+    }
 }
 
 impl SocketAddrV4 {
@@ -99,9 +119,17 @@ impl SocketAddrV4 {
         }
     }
 
+    /// Change the IP address associated with this socket address.
+    #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")]
+    pub fn set_ip(&mut self, new_ip: Ipv4Addr) { self.inner.sin_addr = *new_ip.as_inner() }
+
     /// Returns the port number associated with this socket address.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn port(&self) -> u16 { ntoh(self.inner.sin_port) }
+
+    /// Change the port number associated with this socket address.
+    #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")]
+    pub fn set_port(&mut self, new_port: u16) { self.inner.sin_port = hton(new_port) }
 }
 
 impl SocketAddrV6 {
@@ -130,19 +158,39 @@ impl SocketAddrV6 {
         }
     }
 
+    /// Change the IP address associated with this socket address.
+    #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")]
+    pub fn set_ip(&mut self, new_ip: Ipv6Addr) { self.inner.sin6_addr = *new_ip.as_inner() }
+
     /// Returns the port number associated with this socket address.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn port(&self) -> u16 { ntoh(self.inner.sin6_port) }
 
+    /// Change the port number associated with this socket address.
+    #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")]
+    pub fn set_port(&mut self, new_port: u16) { self.inner.sin6_port = hton(new_port) }
+
     /// Returns the flow information associated with this address,
     /// corresponding to the `sin6_flowinfo` field in C.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn flowinfo(&self) -> u32 { ntoh(self.inner.sin6_flowinfo) }
 
+    /// Change the flow information associated with this socket address.
+    #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")]
+    pub fn set_flowinfo(&mut self, new_flowinfo: u32) {
+        self.inner.sin6_flowinfo = hton(new_flowinfo)
+    }
+
     /// Returns the scope ID associated with this address,
     /// corresponding to the `sin6_scope_id` field in C.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn scope_id(&self) -> u32 { ntoh(self.inner.sin6_scope_id) }
+
+    /// Change the scope ID associated with this socket address.
+    #[unstable(feature = "sockaddr_setters", reason = "recent addition", issue = "31572")]
+    pub fn set_scope_id(&mut self, new_scope_id: u32) {
+        self.inner.sin6_scope_id = hton(new_scope_id)
+    }
 }
 
 impl FromInner<c::sockaddr_in> for SocketAddrV4 {
@@ -385,16 +433,9 @@ impl ToSocketAddrs for (Ipv6Addr, u16) {
 fn resolve_socket_addr(s: &str, p: u16) -> io::Result<vec::IntoIter<SocketAddr>> {
     let ips = try!(lookup_host(s));
     let v: Vec<_> = try!(ips.map(|a| {
-        a.map(|a| {
-            match a {
-                SocketAddr::V4(ref a) => {
-                    SocketAddr::V4(SocketAddrV4::new(*a.ip(), p))
-                }
-                SocketAddr::V6(ref a) => {
-                    SocketAddr::V6(SocketAddrV6::new(*a.ip(), p, a.flowinfo(),
-                                                     a.scope_id()))
-                }
-            }
+        a.map(|mut a| {
+            a.set_port(p);
+            a
         })
     }).collect());
     Ok(v.into_iter())
@@ -511,4 +552,73 @@ mod tests {
     fn to_socket_addr_str_bad() {
         assert!(tsa("1200::AB00:1234::2552:7777:1313:34300").is_err());
     }
+
+    #[test]
+    fn set_ip() {
+        fn ip4(low: u8) -> Ipv4Addr { Ipv4Addr::new(77, 88, 21, low) }
+        fn ip6(low: u16) -> Ipv6Addr { Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, low) }
+
+        let mut v4 = SocketAddrV4::new(ip4(11), 80);
+        assert_eq!(v4.ip(), &ip4(11));
+        v4.set_ip(ip4(12));
+        assert_eq!(v4.ip(), &ip4(12));
+
+        let mut addr = SocketAddr::V4(v4);
+        assert_eq!(addr.ip(), IpAddr::V4(ip4(12)));
+        addr.set_ip(IpAddr::V4(ip4(13)));
+        assert_eq!(addr.ip(), IpAddr::V4(ip4(13)));
+        addr.set_ip(IpAddr::V6(ip6(14)));
+        assert_eq!(addr.ip(), IpAddr::V6(ip6(14)));
+
+        let mut v6 = SocketAddrV6::new(ip6(1), 80, 0, 0);
+        assert_eq!(v6.ip(), &ip6(1));
+        v6.set_ip(ip6(2));
+        assert_eq!(v6.ip(), &ip6(2));
+
+        let mut addr = SocketAddr::V6(v6);
+        assert_eq!(addr.ip(), IpAddr::V6(ip6(2)));
+        addr.set_ip(IpAddr::V6(ip6(3)));
+        assert_eq!(addr.ip(), IpAddr::V6(ip6(3)));
+        addr.set_ip(IpAddr::V4(ip4(4)));
+        assert_eq!(addr.ip(), IpAddr::V4(ip4(4)));
+    }
+
+    #[test]
+    fn set_port() {
+        let mut v4 = SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80);
+        assert_eq!(v4.port(), 80);
+        v4.set_port(443);
+        assert_eq!(v4.port(), 443);
+
+        let mut addr = SocketAddr::V4(v4);
+        assert_eq!(addr.port(), 443);
+        addr.set_port(8080);
+        assert_eq!(addr.port(), 8080);
+
+        let mut v6 = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 0, 0);
+        assert_eq!(v6.port(), 80);
+        v6.set_port(443);
+        assert_eq!(v6.port(), 443);
+
+        let mut addr = SocketAddr::V6(v6);
+        assert_eq!(addr.port(), 443);
+        addr.set_port(8080);
+        assert_eq!(addr.port(), 8080);
+    }
+
+    #[test]
+    fn set_flowinfo() {
+        let mut v6 = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 10, 0);
+        assert_eq!(v6.flowinfo(), 10);
+        v6.set_flowinfo(20);
+        assert_eq!(v6.flowinfo(), 20);
+    }
+
+    #[test]
+    fn set_scope_id() {
+        let mut v6 = SocketAddrV6::new(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 80, 0, 10);
+        assert_eq!(v6.scope_id(), 10);
+        v6.set_scope_id(20);
+        assert_eq!(v6.scope_id(), 20);
+    }
 }