From 2d397084efb54aabeb0a48d82cfa7c6706734f71 Mon Sep 17 00:00:00 2001 From: DCjanus Date: Sun, 18 Aug 2019 11:46:42 +0800 Subject: [PATCH 01/14] Implement an async version of ToSocketAddrs --- src/net/addr.rs | 303 ++++++++++++++++++++++++++++++++++++++++++++++++ src/net/mod.rs | 2 + 2 files changed, 305 insertions(+) create mode 100644 src/net/addr.rs diff --git a/src/net/addr.rs b/src/net/addr.rs new file mode 100644 index 000000000..d92f71f33 --- /dev/null +++ b/src/net/addr.rs @@ -0,0 +1,303 @@ +use crate::future::Future; +use crate::task::blocking::JoinHandle; +use futures::future::{ready, Ready}; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; +pub use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6}; + +/// A trait for objects which can be converted or resolved to one or more +/// [`SocketAddr`] values. +/// +/// This trait is an async version of [`std::net::ToSocketAddrs`]. +/// +/// [`std::net::ToSocketAddrs`]: https://doc.rust-lang.org/std/net/trait.ToSocketAddrs.html +pub trait ToSocketAddrs { + /// Returned iterator over socket addresses which this type may correspond + /// to. + type Iter: Iterator + Send; + /// Returned Future + type Output: Future> + Send; + /// Converts this object to an iterator of resolved `SocketAddr`s. + /// + /// The returned iterator may not actually yield any values depending on the + /// outcome of any resolution performed. + /// + /// Note that this function may block the current thread while resolution is + /// performed. + fn to_socket_addrs(&self) -> Self::Output; +} + +impl ToSocketAddrs for SocketAddr { + type Iter = std::option::IntoIter; + type Output = Ready>; + + fn to_socket_addrs(&self) -> Self::Output { + ready(std::net::ToSocketAddrs::to_socket_addrs(self)) + } +} + +impl ToSocketAddrs for SocketAddrV4 { + type Iter = std::option::IntoIter; + type Output = Ready>; + + fn to_socket_addrs(&self) -> Self::Output { + ready(std::net::ToSocketAddrs::to_socket_addrs(self)) + } +} + +impl ToSocketAddrs for SocketAddrV6 { + type Iter = std::option::IntoIter; + type Output = Ready>; + + fn to_socket_addrs(&self) -> Self::Output { + ready(std::net::ToSocketAddrs::to_socket_addrs(self)) + } +} + +impl ToSocketAddrs for (IpAddr, u16) { + type Iter = std::option::IntoIter; + type Output = Ready>; + + fn to_socket_addrs(&self) -> Self::Output { + ready(std::net::ToSocketAddrs::to_socket_addrs(self)) + } +} + +impl ToSocketAddrs for (Ipv4Addr, u16) { + type Iter = std::option::IntoIter; + type Output = Ready>; + + fn to_socket_addrs(&self) -> Self::Output { + ready(std::net::ToSocketAddrs::to_socket_addrs(self)) + } +} + +impl ToSocketAddrs for (Ipv6Addr, u16) { + type Iter = std::option::IntoIter; + type Output = Ready>; + + fn to_socket_addrs(&self) -> Self::Output { + ready(std::net::ToSocketAddrs::to_socket_addrs(self)) + } +} + +impl ToSocketAddrs for (&str, u16) { + type Iter = std::vec::IntoIter; + type Output = JoinHandle>; + + fn to_socket_addrs(&self) -> Self::Output { + let host = self.0.to_string(); + let port = self.1; + crate::task::blocking::spawn(async move { + std::net::ToSocketAddrs::to_socket_addrs(&(host.as_str(), port)) + }) + } +} + +impl ToSocketAddrs for str { + type Iter = std::vec::IntoIter; + type Output = JoinHandle>; + + fn to_socket_addrs(&self) -> Self::Output { + let host = self.to_string(); + crate::task::blocking::spawn(async move { std::net::ToSocketAddrs::to_socket_addrs(&host) }) + } +} + +impl<'a> ToSocketAddrs for &'a [SocketAddr] { + type Iter = std::iter::Cloned>; + type Output = Ready>; + + fn to_socket_addrs(&self) -> Self::Output { + ready(std::net::ToSocketAddrs::to_socket_addrs(self)) + } +} + +impl ToSocketAddrs for &T { + type Iter = T::Iter; + type Output = T::Output; + + fn to_socket_addrs(&self) -> Self::Output { + (**self).to_socket_addrs() + } +} + +impl ToSocketAddrs for String { + type Iter = std::vec::IntoIter; + type Output = JoinHandle>; + + fn to_socket_addrs(&self) -> Self::Output { + ToSocketAddrs::to_socket_addrs(self.as_str()) + } +} + +#[cfg(all(test, not(target_os = "emscripten")))] +mod tests { + use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; + + use crate::net::*; + + fn tsa(a: A) -> Result, String> { + let socket_addrs = crate::task::block_on(a.to_socket_addrs()); + match socket_addrs { + Ok(a) => Ok(a.collect()), + Err(e) => Err(e.to_string()), + } + } + + pub fn sa4(a: Ipv4Addr, p: u16) -> SocketAddr { + SocketAddr::V4(SocketAddrV4::new(a, p)) + } + + pub fn sa6(a: Ipv6Addr, p: u16) -> SocketAddr { + SocketAddr::V6(SocketAddrV6::new(a, p, 0, 0)) + } + + #[test] + fn to_socket_addr_ipaddr_u16() { + let a = Ipv4Addr::new(77, 88, 21, 11); + let p = 12345; + let e = SocketAddr::V4(SocketAddrV4::new(a, p)); + assert_eq!(Ok(vec![e]), tsa((a, p))); + } + + #[test] + fn to_socket_addr_str_u16() { + let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352); + assert_eq!(Ok(vec![a]), tsa(("77.88.21.11", 24352))); + + let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53); + assert_eq!(Ok(vec![a]), tsa(("2a02:6b8:0:1::1", 53))); + + let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924); + #[cfg(not(target_env = "sgx"))] + assert!(tsa(("localhost", 23924)).unwrap().contains(&a)); + #[cfg(target_env = "sgx")] + let _ = a; + } + + #[test] + fn to_socket_addr_str() { + let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352); + assert_eq!(Ok(vec![a]), tsa("77.88.21.11:24352")); + + let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53); + assert_eq!(Ok(vec![a]), tsa("[2a02:6b8:0:1::1]:53")); + + let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924); + #[cfg(not(target_env = "sgx"))] + assert!(tsa("localhost:23924").unwrap().contains(&a)); + #[cfg(target_env = "sgx")] + let _ = a; + } + + #[test] + fn to_socket_addr_string() { + let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352); + assert_eq!(Ok(vec![a]), tsa(&*format!("{}:{}", "77.88.21.11", "24352"))); + assert_eq!(Ok(vec![a]), tsa(&format!("{}:{}", "77.88.21.11", "24352"))); + assert_eq!(Ok(vec![a]), tsa(format!("{}:{}", "77.88.21.11", "24352"))); + + let s = format!("{}:{}", "77.88.21.11", "24352"); + assert_eq!(Ok(vec![a]), tsa(s)); + // s has been moved into the tsa call + } + + // FIXME: figure out why this fails on openbsd and fix it + #[test] + #[cfg(not(any(windows, target_os = "openbsd")))] + 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); + } + + #[test] + fn is_v4() { + let v4 = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80)); + assert!(v4.is_ipv4()); + assert!(!v4.is_ipv6()); + } + + #[test] + fn is_v6() { + let v6 = SocketAddr::V6(SocketAddrV6::new( + Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), + 80, + 10, + 0, + )); + assert!(!v6.is_ipv4()); + assert!(v6.is_ipv6()); + } +} diff --git a/src/net/mod.rs b/src/net/mod.rs index db4bd3c3d..caf0f5562 100644 --- a/src/net/mod.rs +++ b/src/net/mod.rs @@ -28,9 +28,11 @@ //! # }) } //! ``` +pub use self::addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs}; pub use tcp::{Incoming, TcpListener, TcpStream}; pub use udp::UdpSocket; +mod addr; pub(crate) mod driver; mod tcp; mod udp; From 4ad633eea1fcbc92a6fc27c8e90a9447201f91a3 Mon Sep 17 00:00:00 2001 From: DCjanus Date: Sun, 18 Aug 2019 20:48:21 +0800 Subject: [PATCH 02/14] fix documentation issue --- src/net/addr.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/net/addr.rs b/src/net/addr.rs index d92f71f33..33c3baf28 100644 --- a/src/net/addr.rs +++ b/src/net/addr.rs @@ -21,7 +21,7 @@ pub trait ToSocketAddrs { /// The returned iterator may not actually yield any values depending on the /// outcome of any resolution performed. /// - /// Note that this function may block the current thread while resolution is + /// Note that this function may block a backend thread while resolution is /// performed. fn to_socket_addrs(&self) -> Self::Output; } @@ -132,9 +132,8 @@ impl ToSocketAddrs for String { #[cfg(all(test, not(target_os = "emscripten")))] mod tests { - use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; - use crate::net::*; + use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; fn tsa(a: A) -> Result, String> { let socket_addrs = crate::task::block_on(a.to_socket_addrs()); From 7cba6c4efe71db66050a6f18e980a560b58c40af Mon Sep 17 00:00:00 2001 From: DCjanus Date: Mon, 19 Aug 2019 02:39:22 +0800 Subject: [PATCH 03/14] genius hack: pretending to be `impl Future` --- src/net/addr.rs | 103 +++++++++++++++++++++++++++++++----------------- 1 file changed, 66 insertions(+), 37 deletions(-) diff --git a/src/net/addr.rs b/src/net/addr.rs index 33c3baf28..07bd1cda2 100644 --- a/src/net/addr.rs +++ b/src/net/addr.rs @@ -1,8 +1,25 @@ use crate::future::Future; use crate::task::blocking::JoinHandle; +use cfg_if::cfg_if; use futures::future::{ready, Ready}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; pub use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6}; +use std::pin::Pin; + +cfg_if! { + if #[cfg(feature = "docs")] { + #[doc(hidden)] + pub struct ImplFuture(std::marker::PhantomData); + + macro_rules! ret { + ($f:tt, $i:ty) => (ImplFuture>); + } + } else { + macro_rules! ret { + ($f:tt, $i:ty) => ($f<$i>); + } + } +} /// A trait for objects which can be converted or resolved to one or more /// [`SocketAddr`] values. @@ -14,8 +31,6 @@ pub trait ToSocketAddrs { /// Returned iterator over socket addresses which this type may correspond /// to. type Iter: Iterator + Send; - /// Returned Future - type Output: Future> + Send; /// Converts this object to an iterator of resolved `SocketAddr`s. /// /// The returned iterator may not actually yield any values depending on the @@ -23,109 +38,123 @@ pub trait ToSocketAddrs { /// /// Note that this function may block a backend thread while resolution is /// performed. - fn to_socket_addrs(&self) -> Self::Output; + fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter); +} + +#[doc(hidden)] +#[allow(missing_debug_implementations)] +pub enum ToSocketAddrsFuture> { + Join(JoinHandle>), + Ready(Ready>), +} + +impl> Future for ToSocketAddrsFuture { + type Output = crate::io::Result; + + fn poll( + self: Pin<&mut Self>, + cx: &mut crate::task::Context<'_>, + ) -> crate::task::Poll { + match self.get_mut() { + ToSocketAddrsFuture::Join(f) => Pin::new(&mut *f).poll(cx), + ToSocketAddrsFuture::Ready(f) => Pin::new(&mut *f).poll(cx), + } + } } impl ToSocketAddrs for SocketAddr { type Iter = std::option::IntoIter; - type Output = Ready>; - fn to_socket_addrs(&self) -> Self::Output { - ready(std::net::ToSocketAddrs::to_socket_addrs(self)) + fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + ToSocketAddrsFuture::Ready(ready(std::net::ToSocketAddrs::to_socket_addrs(self))) } } impl ToSocketAddrs for SocketAddrV4 { type Iter = std::option::IntoIter; - type Output = Ready>; - fn to_socket_addrs(&self) -> Self::Output { - ready(std::net::ToSocketAddrs::to_socket_addrs(self)) + fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + ToSocketAddrsFuture::Ready(ready(std::net::ToSocketAddrs::to_socket_addrs(self))) } } impl ToSocketAddrs for SocketAddrV6 { type Iter = std::option::IntoIter; - type Output = Ready>; - fn to_socket_addrs(&self) -> Self::Output { - ready(std::net::ToSocketAddrs::to_socket_addrs(self)) + fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + ToSocketAddrsFuture::Ready(ready(std::net::ToSocketAddrs::to_socket_addrs(self))) } } impl ToSocketAddrs for (IpAddr, u16) { type Iter = std::option::IntoIter; - type Output = Ready>; - fn to_socket_addrs(&self) -> Self::Output { - ready(std::net::ToSocketAddrs::to_socket_addrs(self)) + fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + ToSocketAddrsFuture::Ready(ready(std::net::ToSocketAddrs::to_socket_addrs(self))) } } impl ToSocketAddrs for (Ipv4Addr, u16) { type Iter = std::option::IntoIter; - type Output = Ready>; - fn to_socket_addrs(&self) -> Self::Output { - ready(std::net::ToSocketAddrs::to_socket_addrs(self)) + fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + ToSocketAddrsFuture::Ready(ready(std::net::ToSocketAddrs::to_socket_addrs(self))) } } impl ToSocketAddrs for (Ipv6Addr, u16) { type Iter = std::option::IntoIter; - type Output = Ready>; - fn to_socket_addrs(&self) -> Self::Output { - ready(std::net::ToSocketAddrs::to_socket_addrs(self)) + fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + ToSocketAddrsFuture::Ready(ready(std::net::ToSocketAddrs::to_socket_addrs(self))) } } impl ToSocketAddrs for (&str, u16) { type Iter = std::vec::IntoIter; - type Output = JoinHandle>; - fn to_socket_addrs(&self) -> Self::Output { + fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { let host = self.0.to_string(); let port = self.1; - crate::task::blocking::spawn(async move { + let join = crate::task::blocking::spawn(async move { std::net::ToSocketAddrs::to_socket_addrs(&(host.as_str(), port)) - }) + }); + ToSocketAddrsFuture::Join(join) } } impl ToSocketAddrs for str { type Iter = std::vec::IntoIter; - type Output = JoinHandle>; - fn to_socket_addrs(&self) -> Self::Output { - let host = self.to_string(); - crate::task::blocking::spawn(async move { std::net::ToSocketAddrs::to_socket_addrs(&host) }) + fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + let socket_addrs = self.to_string(); + let join = crate::task::blocking::spawn(async move { + std::net::ToSocketAddrs::to_socket_addrs(&socket_addrs) + }); + ToSocketAddrsFuture::Join(join) } } impl<'a> ToSocketAddrs for &'a [SocketAddr] { type Iter = std::iter::Cloned>; - type Output = Ready>; - fn to_socket_addrs(&self) -> Self::Output { - ready(std::net::ToSocketAddrs::to_socket_addrs(self)) + fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + ToSocketAddrsFuture::Ready(ready(std::net::ToSocketAddrs::to_socket_addrs(self))) } } -impl ToSocketAddrs for &T { +impl ToSocketAddrs for &T { type Iter = T::Iter; - type Output = T::Output; - fn to_socket_addrs(&self) -> Self::Output { + fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { (**self).to_socket_addrs() } } impl ToSocketAddrs for String { type Iter = std::vec::IntoIter; - type Output = JoinHandle>; - fn to_socket_addrs(&self) -> Self::Output { + fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { ToSocketAddrs::to_socket_addrs(self.as_str()) } } From 8baf8dfc0972e67057b319ab68ddc16238efaa98 Mon Sep 17 00:00:00 2001 From: DCjanus Date: Tue, 20 Aug 2019 21:35:31 +0800 Subject: [PATCH 04/14] replace `std::net::ToSocketAddrs` with `async-std::net::ToSocketAddrs` --- src/net/tcp/listener.rs | 10 +++++----- src/net/tcp/stream.rs | 10 +++++----- src/net/udp/mod.rs | 15 ++++++++------- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/net/tcp/listener.rs b/src/net/tcp/listener.rs index 60a96897a..fe4745215 100644 --- a/src/net/tcp/listener.rs +++ b/src/net/tcp/listener.rs @@ -1,4 +1,3 @@ -use std::net::{self, SocketAddr, ToSocketAddrs}; use std::pin::Pin; use cfg_if::cfg_if; @@ -8,6 +7,7 @@ use super::TcpStream; use crate::future::Future; use crate::io; use crate::net::driver::IoHandle; +use crate::net::{SocketAddr, ToSocketAddrs}; use crate::task::{Context, Poll}; /// A TCP socket server, listening for connections. @@ -82,7 +82,7 @@ impl TcpListener { pub async fn bind(addrs: A) -> io::Result { let mut last_err = None; - for addr in addrs.to_socket_addrs()? { + for addr in addrs.to_socket_addrs().await? { match mio::net::TcpListener::bind(&addr) { Ok(mio_listener) => { #[cfg(unix)] @@ -236,9 +236,9 @@ impl<'a> futures::Stream for Incoming<'a> { } } -impl From for TcpListener { +impl From for TcpListener { /// Converts a `std::net::TcpListener` into its asynchronous equivalent. - fn from(listener: net::TcpListener) -> TcpListener { + fn from(listener: std::net::TcpListener) -> TcpListener { let mio_listener = mio::net::TcpListener::from_std(listener).unwrap(); #[cfg(unix)] @@ -279,7 +279,7 @@ cfg_if! { impl FromRawFd for TcpListener { unsafe fn from_raw_fd(fd: RawFd) -> TcpListener { - net::TcpListener::from_raw_fd(fd).into() + std::net::TcpListener::from_raw_fd(fd).into() } } diff --git a/src/net/tcp/stream.rs b/src/net/tcp/stream.rs index d8233173d..f4e5c2bde 100644 --- a/src/net/tcp/stream.rs +++ b/src/net/tcp/stream.rs @@ -1,6 +1,5 @@ use std::io::{IoSlice, IoSliceMut}; use std::mem; -use std::net::{self, SocketAddr, ToSocketAddrs}; use std::pin::Pin; use cfg_if::cfg_if; @@ -9,6 +8,7 @@ use futures::io::{AsyncRead, AsyncWrite}; use crate::io; use crate::net::driver::IoHandle; +use crate::net::{SocketAddr, ToSocketAddrs}; use crate::task::{Context, Poll}; /// A TCP stream between a local and a remote socket. @@ -80,7 +80,7 @@ impl TcpStream { pub async fn connect(addrs: A) -> io::Result { let mut last_err = None; - for addr in addrs.to_socket_addrs()? { + for addr in addrs.to_socket_addrs().await? { let res = Self::connect_to(addr).await; match res { @@ -437,9 +437,9 @@ impl AsyncWrite for &TcpStream { } } -impl From for TcpStream { +impl From for TcpStream { /// Converts a `std::net::TcpStream` into its asynchronous equivalent. - fn from(stream: net::TcpStream) -> TcpStream { + fn from(stream: std::net::TcpStream) -> TcpStream { let mio_stream = mio::net::TcpStream::from_stream(stream).unwrap(); #[cfg(unix)] @@ -480,7 +480,7 @@ cfg_if! { impl FromRawFd for TcpStream { unsafe fn from_raw_fd(fd: RawFd) -> TcpStream { - net::TcpStream::from_raw_fd(fd).into() + std::net::TcpStream::from_raw_fd(fd).into() } } diff --git a/src/net/udp/mod.rs b/src/net/udp/mod.rs index 3e9e749a8..c197d98c8 100644 --- a/src/net/udp/mod.rs +++ b/src/net/udp/mod.rs @@ -1,9 +1,10 @@ use std::io; -use std::net::{self, Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs}; use cfg_if::cfg_if; use futures::future; +use std::net::{Ipv4Addr, Ipv6Addr}; +use crate::net::addr::{SocketAddr, ToSocketAddrs}; use crate::net::driver::IoHandle; use crate::task::Poll; @@ -75,7 +76,7 @@ impl UdpSocket { pub async fn bind(addr: A) -> io::Result { let mut last_err = None; - for addr in addr.to_socket_addrs()? { + for addr in addr.to_socket_addrs().await? { match mio::net::UdpSocket::bind(&addr) { Ok(mio_socket) => { #[cfg(unix)] @@ -152,7 +153,7 @@ impl UdpSocket { /// # Ok(()) }) } /// ``` pub async fn send_to(&self, buf: &[u8], addrs: A) -> io::Result { - let addr = match addrs.to_socket_addrs()?.next() { + let addr = match addrs.to_socket_addrs().await?.next() { Some(addr) => addr, None => { return Err(io::Error::new( @@ -237,7 +238,7 @@ impl UdpSocket { pub async fn connect(&self, addrs: A) -> io::Result<()> { let mut last_err = None; - for addr in addrs.to_socket_addrs()? { + for addr in addrs.to_socket_addrs().await? { match self.io_handle.get_ref().connect(addr) { Ok(()) => return Ok(()), Err(err) => last_err = Some(err), @@ -506,9 +507,9 @@ impl UdpSocket { } } -impl From for UdpSocket { +impl From for UdpSocket { /// Converts a `std::net::UdpSocket` into its asynchronous equivalent. - fn from(socket: net::UdpSocket) -> UdpSocket { + fn from(socket: std::net::UdpSocket) -> UdpSocket { let mio_socket = mio::net::UdpSocket::from_socket(socket).unwrap(); #[cfg(unix)] @@ -549,7 +550,7 @@ cfg_if! { impl FromRawFd for UdpSocket { unsafe fn from_raw_fd(fd: RawFd) -> UdpSocket { - net::UdpSocket::from_raw_fd(fd).into() + std::net::UdpSocket::from_raw_fd(fd).into() } } From e1b49351a63b1603e9619aad5dd35bf447162de0 Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Fri, 23 Aug 2019 19:17:42 +0200 Subject: [PATCH 05/14] Move unit tests into the tests directory --- src/net/addr.rs | 171 ------------------------------------------------ src/net/mod.rs | 2 +- tests/addr.rs | 77 ++++++++++++++++++++++ 3 files changed, 78 insertions(+), 172 deletions(-) create mode 100644 tests/addr.rs diff --git a/src/net/addr.rs b/src/net/addr.rs index 07bd1cda2..c3e3ac9a6 100644 --- a/src/net/addr.rs +++ b/src/net/addr.rs @@ -158,174 +158,3 @@ impl ToSocketAddrs for String { ToSocketAddrs::to_socket_addrs(self.as_str()) } } - -#[cfg(all(test, not(target_os = "emscripten")))] -mod tests { - use crate::net::*; - use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; - - fn tsa(a: A) -> Result, String> { - let socket_addrs = crate::task::block_on(a.to_socket_addrs()); - match socket_addrs { - Ok(a) => Ok(a.collect()), - Err(e) => Err(e.to_string()), - } - } - - pub fn sa4(a: Ipv4Addr, p: u16) -> SocketAddr { - SocketAddr::V4(SocketAddrV4::new(a, p)) - } - - pub fn sa6(a: Ipv6Addr, p: u16) -> SocketAddr { - SocketAddr::V6(SocketAddrV6::new(a, p, 0, 0)) - } - - #[test] - fn to_socket_addr_ipaddr_u16() { - let a = Ipv4Addr::new(77, 88, 21, 11); - let p = 12345; - let e = SocketAddr::V4(SocketAddrV4::new(a, p)); - assert_eq!(Ok(vec![e]), tsa((a, p))); - } - - #[test] - fn to_socket_addr_str_u16() { - let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352); - assert_eq!(Ok(vec![a]), tsa(("77.88.21.11", 24352))); - - let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53); - assert_eq!(Ok(vec![a]), tsa(("2a02:6b8:0:1::1", 53))); - - let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924); - #[cfg(not(target_env = "sgx"))] - assert!(tsa(("localhost", 23924)).unwrap().contains(&a)); - #[cfg(target_env = "sgx")] - let _ = a; - } - - #[test] - fn to_socket_addr_str() { - let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352); - assert_eq!(Ok(vec![a]), tsa("77.88.21.11:24352")); - - let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53); - assert_eq!(Ok(vec![a]), tsa("[2a02:6b8:0:1::1]:53")); - - let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924); - #[cfg(not(target_env = "sgx"))] - assert!(tsa("localhost:23924").unwrap().contains(&a)); - #[cfg(target_env = "sgx")] - let _ = a; - } - - #[test] - fn to_socket_addr_string() { - let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352); - assert_eq!(Ok(vec![a]), tsa(&*format!("{}:{}", "77.88.21.11", "24352"))); - assert_eq!(Ok(vec![a]), tsa(&format!("{}:{}", "77.88.21.11", "24352"))); - assert_eq!(Ok(vec![a]), tsa(format!("{}:{}", "77.88.21.11", "24352"))); - - let s = format!("{}:{}", "77.88.21.11", "24352"); - assert_eq!(Ok(vec![a]), tsa(s)); - // s has been moved into the tsa call - } - - // FIXME: figure out why this fails on openbsd and fix it - #[test] - #[cfg(not(any(windows, target_os = "openbsd")))] - 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); - } - - #[test] - fn is_v4() { - let v4 = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 80)); - assert!(v4.is_ipv4()); - assert!(!v4.is_ipv6()); - } - - #[test] - fn is_v6() { - let v6 = SocketAddr::V6(SocketAddrV6::new( - Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), - 80, - 10, - 0, - )); - assert!(!v6.is_ipv4()); - assert!(v6.is_ipv6()); - } -} diff --git a/src/net/mod.rs b/src/net/mod.rs index caf0f5562..b57f456bd 100644 --- a/src/net/mod.rs +++ b/src/net/mod.rs @@ -28,7 +28,7 @@ //! # }) } //! ``` -pub use self::addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs}; +pub use addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs}; pub use tcp::{Incoming, TcpListener, TcpStream}; pub use udp::UdpSocket; diff --git a/tests/addr.rs b/tests/addr.rs new file mode 100644 index 000000000..5635c6e1b --- /dev/null +++ b/tests/addr.rs @@ -0,0 +1,77 @@ +use std::net::{Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6}; + +use async_std::net::{SocketAddr, ToSocketAddrs}; +use async_std::task; + +fn tsa(a: A) -> Result, String> { + let socket_addrs = task::block_on(a.to_socket_addrs()); + match socket_addrs { + Ok(a) => Ok(a.collect()), + Err(e) => Err(e.to_string()), + } +} + +pub fn sa4(a: Ipv4Addr, p: u16) -> SocketAddr { + SocketAddr::V4(SocketAddrV4::new(a, p)) +} + +pub fn sa6(a: Ipv6Addr, p: u16) -> SocketAddr { + SocketAddr::V6(SocketAddrV6::new(a, p, 0, 0)) +} + +#[test] +fn to_socket_addr_ipaddr_u16() { + let a = Ipv4Addr::new(77, 88, 21, 11); + let p = 12345; + let e = SocketAddr::V4(SocketAddrV4::new(a, p)); + assert_eq!(Ok(vec![e]), tsa((a, p))); +} + +#[test] +fn to_socket_addr_str_u16() { + let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352); + assert_eq!(Ok(vec![a]), tsa(("77.88.21.11", 24352))); + + let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53); + assert_eq!(Ok(vec![a]), tsa(("2a02:6b8:0:1::1", 53))); + + let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924); + #[cfg(not(target_env = "sgx"))] + assert!(tsa(("localhost", 23924)).unwrap().contains(&a)); + #[cfg(target_env = "sgx")] + let _ = a; +} + +#[test] +fn to_socket_addr_str() { + let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352); + assert_eq!(Ok(vec![a]), tsa("77.88.21.11:24352")); + + let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53); + assert_eq!(Ok(vec![a]), tsa("[2a02:6b8:0:1::1]:53")); + + let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924); + #[cfg(not(target_env = "sgx"))] + assert!(tsa("localhost:23924").unwrap().contains(&a)); + #[cfg(target_env = "sgx")] + let _ = a; +} + +#[test] +fn to_socket_addr_string() { + let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352); + assert_eq!(Ok(vec![a]), tsa(&*format!("{}:{}", "77.88.21.11", "24352"))); + assert_eq!(Ok(vec![a]), tsa(&format!("{}:{}", "77.88.21.11", "24352"))); + assert_eq!(Ok(vec![a]), tsa(format!("{}:{}", "77.88.21.11", "24352"))); + + let s = format!("{}:{}", "77.88.21.11", "24352"); + assert_eq!(Ok(vec![a]), tsa(s)); + // s has been moved into the tsa call +} + +// FIXME: figure out why this fails on openbsd and fix it +#[test] +#[cfg(not(any(windows, target_os = "openbsd")))] +fn to_socket_addr_str_bad() { + assert!(tsa("1200::AB00:1234::2552:7777:1313:34300").is_err()); +} From 11cdff793f1043782fcd6e43165105b9bd00180c Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Fri, 23 Aug 2019 19:27:10 +0200 Subject: [PATCH 06/14] Stylistic changes --- src/net/addr.rs | 48 ++++++++++++++++++++++------------------------ src/net/mod.rs | 4 +++- src/net/udp/mod.rs | 2 +- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/net/addr.rs b/src/net/addr.rs index c3e3ac9a6..5cbc691a1 100644 --- a/src/net/addr.rs +++ b/src/net/addr.rs @@ -1,18 +1,22 @@ -use crate::future::Future; -use crate::task::blocking::JoinHandle; -use cfg_if::cfg_if; -use futures::future::{ready, Ready}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; -pub use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6}; +use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6}; use std::pin::Pin; +use cfg_if::cfg_if; +use futures::future::{ready, Ready}; + +use crate::future::Future; +use crate::io; +use crate::task::blocking; +use crate::task::{Context, Poll}; + cfg_if! { if #[cfg(feature = "docs")] { #[doc(hidden)] pub struct ImplFuture(std::marker::PhantomData); macro_rules! ret { - ($f:tt, $i:ty) => (ImplFuture>); + ($f:tt, $i:ty) => (ImplFuture>); } } else { macro_rules! ret { @@ -21,40 +25,35 @@ cfg_if! { } } -/// A trait for objects which can be converted or resolved to one or more -/// [`SocketAddr`] values. +/// A trait for objects which can be converted or resolved to one or more [`SocketAddr`] values. /// /// This trait is an async version of [`std::net::ToSocketAddrs`]. /// /// [`std::net::ToSocketAddrs`]: https://doc.rust-lang.org/std/net/trait.ToSocketAddrs.html pub trait ToSocketAddrs { - /// Returned iterator over socket addresses which this type may correspond - /// to. + /// Returned iterator over socket addresses which this type may correspond to. type Iter: Iterator + Send; + /// Converts this object to an iterator of resolved `SocketAddr`s. /// - /// The returned iterator may not actually yield any values depending on the - /// outcome of any resolution performed. + /// The returned iterator may not actually yield any values depending on the outcome of any + /// resolution performed. /// - /// Note that this function may block a backend thread while resolution is - /// performed. + /// Note that this function may block a backend thread while resolution is performed. fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter); } #[doc(hidden)] #[allow(missing_debug_implementations)] pub enum ToSocketAddrsFuture> { - Join(JoinHandle>), - Ready(Ready>), + Join(blocking::JoinHandle>), + Ready(Ready>), } impl> Future for ToSocketAddrsFuture { - type Output = crate::io::Result; + type Output = io::Result; - fn poll( - self: Pin<&mut Self>, - cx: &mut crate::task::Context<'_>, - ) -> crate::task::Poll { + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { match self.get_mut() { ToSocketAddrsFuture::Join(f) => Pin::new(&mut *f).poll(cx), ToSocketAddrsFuture::Ready(f) => Pin::new(&mut *f).poll(cx), @@ -116,7 +115,7 @@ impl ToSocketAddrs for (&str, u16) { fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { let host = self.0.to_string(); let port = self.1; - let join = crate::task::blocking::spawn(async move { + let join = blocking::spawn(async move { std::net::ToSocketAddrs::to_socket_addrs(&(host.as_str(), port)) }); ToSocketAddrsFuture::Join(join) @@ -128,9 +127,8 @@ impl ToSocketAddrs for str { fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { let socket_addrs = self.to_string(); - let join = crate::task::blocking::spawn(async move { - std::net::ToSocketAddrs::to_socket_addrs(&socket_addrs) - }); + let join = + blocking::spawn(async move { std::net::ToSocketAddrs::to_socket_addrs(&socket_addrs) }); ToSocketAddrsFuture::Join(join) } } diff --git a/src/net/mod.rs b/src/net/mod.rs index b57f456bd..6ec3631f1 100644 --- a/src/net/mod.rs +++ b/src/net/mod.rs @@ -28,7 +28,9 @@ //! # }) } //! ``` -pub use addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs}; +pub use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6}; + +pub use addr::ToSocketAddrs; pub use tcp::{Incoming, TcpListener, TcpStream}; pub use udp::UdpSocket; diff --git a/src/net/udp/mod.rs b/src/net/udp/mod.rs index c197d98c8..455043c85 100644 --- a/src/net/udp/mod.rs +++ b/src/net/udp/mod.rs @@ -4,8 +4,8 @@ use cfg_if::cfg_if; use futures::future; use std::net::{Ipv4Addr, Ipv6Addr}; -use crate::net::addr::{SocketAddr, ToSocketAddrs}; use crate::net::driver::IoHandle; +use crate::net::{SocketAddr, ToSocketAddrs}; use crate::task::Poll; /// A UDP socket. From 815271b9498755f2705a1659b7dac424d6ed1190 Mon Sep 17 00:00:00 2001 From: Stjepan Glavina Date: Fri, 23 Aug 2019 19:29:15 +0200 Subject: [PATCH 07/14] Remove re-exports in async_std::net --- src/net/mod.rs | 2 -- src/net/tcp/listener.rs | 3 ++- src/net/tcp/stream.rs | 3 ++- src/net/udp/mod.rs | 3 ++- tests/addr.rs | 4 ++-- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/net/mod.rs b/src/net/mod.rs index 6ec3631f1..259dc1de5 100644 --- a/src/net/mod.rs +++ b/src/net/mod.rs @@ -28,8 +28,6 @@ //! # }) } //! ``` -pub use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6}; - pub use addr::ToSocketAddrs; pub use tcp::{Incoming, TcpListener, TcpStream}; pub use udp::UdpSocket; diff --git a/src/net/tcp/listener.rs b/src/net/tcp/listener.rs index fe4745215..ac18387a7 100644 --- a/src/net/tcp/listener.rs +++ b/src/net/tcp/listener.rs @@ -1,3 +1,4 @@ +use std::net::SocketAddr; use std::pin::Pin; use cfg_if::cfg_if; @@ -7,7 +8,7 @@ use super::TcpStream; use crate::future::Future; use crate::io; use crate::net::driver::IoHandle; -use crate::net::{SocketAddr, ToSocketAddrs}; +use crate::net::ToSocketAddrs; use crate::task::{Context, Poll}; /// A TCP socket server, listening for connections. diff --git a/src/net/tcp/stream.rs b/src/net/tcp/stream.rs index f4e5c2bde..5ea181f25 100644 --- a/src/net/tcp/stream.rs +++ b/src/net/tcp/stream.rs @@ -1,5 +1,6 @@ use std::io::{IoSlice, IoSliceMut}; use std::mem; +use std::net::SocketAddr; use std::pin::Pin; use cfg_if::cfg_if; @@ -8,7 +9,7 @@ use futures::io::{AsyncRead, AsyncWrite}; use crate::io; use crate::net::driver::IoHandle; -use crate::net::{SocketAddr, ToSocketAddrs}; +use crate::net::ToSocketAddrs; use crate::task::{Context, Poll}; /// A TCP stream between a local and a remote socket. diff --git a/src/net/udp/mod.rs b/src/net/udp/mod.rs index 455043c85..19119a562 100644 --- a/src/net/udp/mod.rs +++ b/src/net/udp/mod.rs @@ -1,11 +1,12 @@ use std::io; +use std::net::SocketAddr; use cfg_if::cfg_if; use futures::future; use std::net::{Ipv4Addr, Ipv6Addr}; use crate::net::driver::IoHandle; -use crate::net::{SocketAddr, ToSocketAddrs}; +use crate::net::ToSocketAddrs; use crate::task::Poll; /// A UDP socket. diff --git a/tests/addr.rs b/tests/addr.rs index 5635c6e1b..153856486 100644 --- a/tests/addr.rs +++ b/tests/addr.rs @@ -1,6 +1,6 @@ -use std::net::{Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6}; +use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; -use async_std::net::{SocketAddr, ToSocketAddrs}; +use async_std::net::ToSocketAddrs; use async_std::task; fn tsa(a: A) -> Result, String> { From dc4d7bd524dbfddd9657c0b97432c57d431bc549 Mon Sep 17 00:00:00 2001 From: DCjanus Date: Wed, 28 Aug 2019 16:05:31 +0800 Subject: [PATCH 08/14] fix broken link --- src/net/addr.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/net/addr.rs b/src/net/addr.rs index 5cbc691a1..b464ef747 100644 --- a/src/net/addr.rs +++ b/src/net/addr.rs @@ -30,6 +30,7 @@ cfg_if! { /// This trait is an async version of [`std::net::ToSocketAddrs`]. /// /// [`std::net::ToSocketAddrs`]: https://doc.rust-lang.org/std/net/trait.ToSocketAddrs.html +/// [`SocketAddr`]: https://doc.rust-lang.org/std/net/enum.SocketAddr.html pub trait ToSocketAddrs { /// Returned iterator over socket addresses which this type may correspond to. type Iter: Iterator + Send; From bfdf6ffabfd07e6464a02a922fd18d7ab037ca6d Mon Sep 17 00:00:00 2001 From: DCjanus Date: Wed, 28 Aug 2019 18:25:27 +0800 Subject: [PATCH 09/14] some mirror changes --- tests/addr.rs | 70 +++++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/tests/addr.rs b/tests/addr.rs index 153856486..c0b90b98d 100644 --- a/tests/addr.rs +++ b/tests/addr.rs @@ -3,7 +3,7 @@ use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; use async_std::net::ToSocketAddrs; use async_std::task; -fn tsa(a: A) -> Result, String> { +fn blocking_resolve(a: A) -> Result, String> { let socket_addrs = task::block_on(a.to_socket_addrs()); match socket_addrs { Ok(a) => Ok(a.collect()), @@ -11,67 +11,77 @@ fn tsa(a: A) -> Result, String> { } } -pub fn sa4(a: Ipv4Addr, p: u16) -> SocketAddr { - SocketAddr::V4(SocketAddrV4::new(a, p)) -} - -pub fn sa6(a: Ipv6Addr, p: u16) -> SocketAddr { - SocketAddr::V6(SocketAddrV6::new(a, p, 0, 0)) -} - #[test] fn to_socket_addr_ipaddr_u16() { let a = Ipv4Addr::new(77, 88, 21, 11); let p = 12345; let e = SocketAddr::V4(SocketAddrV4::new(a, p)); - assert_eq!(Ok(vec![e]), tsa((a, p))); + assert_eq!(Ok(vec![e]), blocking_resolve((a, p))); } #[test] fn to_socket_addr_str_u16() { - let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352); - assert_eq!(Ok(vec![a]), tsa(("77.88.21.11", 24352))); + let a = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 24352)); + assert_eq!(Ok(vec![a]), blocking_resolve(("77.88.21.11", 24352))); - let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53); - assert_eq!(Ok(vec![a]), tsa(("2a02:6b8:0:1::1", 53))); + let a = SocketAddr::V6(SocketAddrV6::new( + Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), + 53, + 0, + 0, + )); + assert_eq!(Ok(vec![a]), blocking_resolve(("2a02:6b8:0:1::1", 53))); - let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924); + let a = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 23924)); #[cfg(not(target_env = "sgx"))] - assert!(tsa(("localhost", 23924)).unwrap().contains(&a)); + assert!(blocking_resolve(("localhost", 23924)).unwrap().contains(&a)); #[cfg(target_env = "sgx")] let _ = a; } #[test] fn to_socket_addr_str() { - let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352); - assert_eq!(Ok(vec![a]), tsa("77.88.21.11:24352")); + let a = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 24352)); + assert_eq!(Ok(vec![a]), blocking_resolve("77.88.21.11:24352")); - let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53); - assert_eq!(Ok(vec![a]), tsa("[2a02:6b8:0:1::1]:53")); + let a = SocketAddr::V6(SocketAddrV6::new( + Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), + 53, + 0, + 0, + )); + assert_eq!(Ok(vec![a]), blocking_resolve("[2a02:6b8:0:1::1]:53")); - let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924); + let a = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 23924)); #[cfg(not(target_env = "sgx"))] - assert!(tsa("localhost:23924").unwrap().contains(&a)); + assert!(blocking_resolve("localhost:23924").unwrap().contains(&a)); #[cfg(target_env = "sgx")] let _ = a; } #[test] fn to_socket_addr_string() { - let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352); - assert_eq!(Ok(vec![a]), tsa(&*format!("{}:{}", "77.88.21.11", "24352"))); - assert_eq!(Ok(vec![a]), tsa(&format!("{}:{}", "77.88.21.11", "24352"))); - assert_eq!(Ok(vec![a]), tsa(format!("{}:{}", "77.88.21.11", "24352"))); + let a = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 24352)); + assert_eq!( + Ok(vec![a]), + blocking_resolve(&*format!("{}:{}", "77.88.21.11", "24352")) + ); + assert_eq!( + Ok(vec![a]), + blocking_resolve(&format!("{}:{}", "77.88.21.11", "24352")) + ); + assert_eq!( + Ok(vec![a]), + blocking_resolve(format!("{}:{}", "77.88.21.11", "24352")) + ); - let s = format!("{}:{}", "77.88.21.11", "24352"); - assert_eq!(Ok(vec![a]), tsa(s)); - // s has been moved into the tsa call + let s = "77.88.21.11:24352"; + assert_eq!(Ok(vec![a]), blocking_resolve(s)); } // FIXME: figure out why this fails on openbsd and fix it #[test] #[cfg(not(any(windows, target_os = "openbsd")))] fn to_socket_addr_str_bad() { - assert!(tsa("1200::AB00:1234::2552:7777:1313:34300").is_err()); + assert!(blocking_resolve("1200::AB00:1234::2552:7777:1313:34300").is_err()); } From 242cc9faec07fdc558828f765f4562d4fcea6411 Mon Sep 17 00:00:00 2001 From: DCjanus Date: Thu, 29 Aug 2019 20:16:51 +0800 Subject: [PATCH 10/14] remove unnecessary format --- tests/addr.rs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/tests/addr.rs b/tests/addr.rs index c0b90b98d..027c8292f 100644 --- a/tests/addr.rs +++ b/tests/addr.rs @@ -62,20 +62,13 @@ fn to_socket_addr_str() { #[test] fn to_socket_addr_string() { let a = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(77, 88, 21, 11), 24352)); - assert_eq!( - Ok(vec![a]), - blocking_resolve(&*format!("{}:{}", "77.88.21.11", "24352")) - ); - assert_eq!( - Ok(vec![a]), - blocking_resolve(&format!("{}:{}", "77.88.21.11", "24352")) - ); - assert_eq!( - Ok(vec![a]), - blocking_resolve(format!("{}:{}", "77.88.21.11", "24352")) - ); + let s: &str = "77.88.21.11:24352"; + assert_eq!(Ok(vec![a]), blocking_resolve(s)); + + let s: &String = &"77.88.21.11:24352".to_string(); + assert_eq!(Ok(vec![a]), blocking_resolve(s)); - let s = "77.88.21.11:24352"; + let s: String = "77.88.21.11:24352".to_string(); assert_eq!(Ok(vec![a]), blocking_resolve(s)); } From 63c2c75a6e94d58a742d3dff7c9ede817dd082f5 Mon Sep 17 00:00:00 2001 From: DCjanus Date: Thu, 29 Aug 2019 21:32:08 +0800 Subject: [PATCH 11/14] migrate: `std::net::ToSocketAddrs` -> `async_std::net::ToSocketAddrs` --- docs/src/tutorial/accept_loop.md | 25 +++++++++------------ docs/src/tutorial/all_together.md | 3 +-- docs/src/tutorial/clean_shutdown.md | 6 ++--- docs/src/tutorial/handling_disconnection.md | 3 +-- docs/src/tutorial/implementing_a_client.md | 3 +-- docs/src/tutorial/receiving_messages.md | 6 ++--- 6 files changed, 17 insertions(+), 29 deletions(-) diff --git a/docs/src/tutorial/accept_loop.md b/docs/src/tutorial/accept_loop.md index d40d3487c..96c15bac9 100644 --- a/docs/src/tutorial/accept_loop.md +++ b/docs/src/tutorial/accept_loop.md @@ -6,23 +6,20 @@ First of all, let's add required import boilerplate: ```rust,edition2018 # extern crate async_std; -use std::net::ToSocketAddrs; // 1 use async_std::{ - prelude::*, // 2 - task, // 3 - net::TcpListener, // 4 + prelude::*, // 1 + task, // 2 + net::{TcpListener, ToSocketAddrs}, // 3 }; -type Result = std::result::Result>; // 5 +type Result = std::result::Result>; // 4 ``` -1. `async_std` uses `std` types where appropriate. - We'll need `ToSocketAddrs` to specify address to listen on. -2. `prelude` re-exports some traits required to work with futures and streams. -3. The `task` module roughly corresponds to the `std::thread` module, but tasks are much lighter weight. +1. `prelude` re-exports some traits required to work with futures and streams. +2. The `task` module roughly corresponds to the `std::thread` module, but tasks are much lighter weight. A single thread can run many tasks. -4. For the socket type, we use `TcpListener` from `async_std`, which is just like `std::net::TcpListener`, but is non-blocking and uses `async` API. -5. We will skip implementing comprehensive error handling in this example. +3. For the socket type, we use `TcpListener` from `async_std`, which is just like `std::net::TcpListener`, but is non-blocking and uses `async` API. +4. We will skip implementing comprehensive error handling in this example. To propagate the errors, we will use a boxed error trait object. Do you know that there's `From<&'_ str> for Box` implementation in stdlib, which allows you to use strings with `?` operator? @@ -31,10 +28,9 @@ Now we can write the server's accept loop: ```rust,edition2018 # extern crate async_std; # use async_std::{ -# net::TcpListener, +# net::{TcpListener, ToSocketAddrs}, # prelude::Stream, # }; -# use std::net::ToSocketAddrs; # # type Result = std::result::Result>; # @@ -69,11 +65,10 @@ Finally, let's add main: ```rust,edition2018 # extern crate async_std; # use async_std::{ -# net::TcpListener, +# net::{TcpListener, ToSocketAddrs}, # prelude::Stream, # task, # }; -# use std::net::ToSocketAddrs; # # type Result = std::result::Result>; # diff --git a/docs/src/tutorial/all_together.md b/docs/src/tutorial/all_together.md index 352d69256..415f3b8e6 100644 --- a/docs/src/tutorial/all_together.md +++ b/docs/src/tutorial/all_together.md @@ -7,7 +7,7 @@ At this point, we only need to start the broker to get a fully-functioning (in t # extern crate futures; use async_std::{ io::{self, BufReader}, - net::{TcpListener, TcpStream}, + net::{TcpListener, TcpStream, ToSocketAddrs}, prelude::*, task, }; @@ -17,7 +17,6 @@ use futures::{ }; use std::{ collections::hash_map::{HashMap, Entry}, - net::ToSocketAddrs, sync::Arc, }; diff --git a/docs/src/tutorial/clean_shutdown.md b/docs/src/tutorial/clean_shutdown.md index 1c2fc76c1..6bf705619 100644 --- a/docs/src/tutorial/clean_shutdown.md +++ b/docs/src/tutorial/clean_shutdown.md @@ -25,7 +25,7 @@ Let's add waiting to the server: # extern crate futures; # use async_std::{ # io::{self, BufReader}, -# net::{TcpListener, TcpStream}, +# net::{TcpListener, TcpStream, ToSocketAddrs}, # prelude::*, # task, # }; @@ -35,7 +35,6 @@ Let's add waiting to the server: # }; # use std::{ # collections::hash_map::{HashMap, Entry}, -# net::ToSocketAddrs, # sync::Arc, # }; # @@ -160,7 +159,7 @@ And to the broker: # extern crate futures; # use async_std::{ # io::{self, BufReader}, -# net::{TcpListener, TcpStream}, +# net::{TcpListener, TcpStream, ToSocketAddrs}, # prelude::*, # task, # }; @@ -170,7 +169,6 @@ And to the broker: # }; # use std::{ # collections::hash_map::{HashMap, Entry}, -# net::ToSocketAddrs, # sync::Arc, # }; # diff --git a/docs/src/tutorial/handling_disconnection.md b/docs/src/tutorial/handling_disconnection.md index 1cc07b230..30827bab4 100644 --- a/docs/src/tutorial/handling_disconnection.md +++ b/docs/src/tutorial/handling_disconnection.md @@ -121,13 +121,12 @@ The final code looks like this: # extern crate futures; use async_std::{ io::{BufReader, BufRead, Write}, - net::{TcpListener, TcpStream}, + net::{TcpListener, TcpStream, ToSocketAddrs}, task, }; use futures::{channel::mpsc, future::Future, select, FutureExt, SinkExt, StreamExt}; use std::{ collections::hash_map::{Entry, HashMap}, - net::ToSocketAddrs, sync::Arc, }; diff --git a/docs/src/tutorial/implementing_a_client.md b/docs/src/tutorial/implementing_a_client.md index 35cccd83c..97e731999 100644 --- a/docs/src/tutorial/implementing_a_client.md +++ b/docs/src/tutorial/implementing_a_client.md @@ -19,11 +19,10 @@ With async, we can just use the `select!` macro. # extern crate futures; use async_std::{ io::{stdin, BufRead, BufReader, Write}, - net::TcpStream, + net::{TcpStream, ToSocketAddrs}, task, }; use futures::{select, FutureExt, StreamExt}; -use std::net::ToSocketAddrs; type Result = std::result::Result>; diff --git a/docs/src/tutorial/receiving_messages.md b/docs/src/tutorial/receiving_messages.md index 9cef56dba..8f26ca518 100644 --- a/docs/src/tutorial/receiving_messages.md +++ b/docs/src/tutorial/receiving_messages.md @@ -11,11 +11,10 @@ We need to: # extern crate async_std; # use async_std::{ # io::{BufRead, BufReader}, -# net::{TcpListener, TcpStream}, +# net::{TcpListener, TcpStream. ToSocketAddrs}, # prelude::Stream, # task, # }; -# use std::net::ToSocketAddrs; # # type Result = std::result::Result>; # @@ -77,11 +76,10 @@ We can "fix" it by waiting for the task to be joined, like this: # extern crate async_std; # use async_std::{ # io::{BufRead, BufReader}, -# net::{TcpListener, TcpStream}, +# net::{TcpListener, TcpStream, ToSocketAddrs}, # prelude::Stream, # task, # }; -# use std::net::ToSocketAddrs; # # type Result = std::result::Result>; # From ff40561871d8dbaf91eb458ad470b63c85fed284 Mon Sep 17 00:00:00 2001 From: DCjanus Date: Thu, 29 Aug 2019 21:42:34 +0800 Subject: [PATCH 12/14] fix typo(tutorial) --- docs/src/tutorial/receiving_messages.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/tutorial/receiving_messages.md b/docs/src/tutorial/receiving_messages.md index 8f26ca518..667cf1cf8 100644 --- a/docs/src/tutorial/receiving_messages.md +++ b/docs/src/tutorial/receiving_messages.md @@ -11,7 +11,7 @@ We need to: # extern crate async_std; # use async_std::{ # io::{BufRead, BufReader}, -# net::{TcpListener, TcpStream. ToSocketAddrs}, +# net::{TcpListener, TcpStream, ToSocketAddrs}, # prelude::Stream, # task, # }; From d2c61b66368ec8ab07f0c1f6dc40a94c15d09670 Mon Sep 17 00:00:00 2001 From: DCjanus Date: Thu, 5 Sep 2019 00:09:26 +0800 Subject: [PATCH 13/14] remove unnecessary type bound --- src/net/addr.rs | 4 ++-- tests/addr.rs | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/net/addr.rs b/src/net/addr.rs index b464ef747..f3dc605da 100644 --- a/src/net/addr.rs +++ b/src/net/addr.rs @@ -33,7 +33,7 @@ cfg_if! { /// [`SocketAddr`]: https://doc.rust-lang.org/std/net/enum.SocketAddr.html pub trait ToSocketAddrs { /// Returned iterator over socket addresses which this type may correspond to. - type Iter: Iterator + Send; + type Iter: Iterator; /// Converts this object to an iterator of resolved `SocketAddr`s. /// @@ -142,7 +142,7 @@ impl<'a> ToSocketAddrs for &'a [SocketAddr] { } } -impl ToSocketAddrs for &T { +impl ToSocketAddrs for &T { type Iter = T::Iter; fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { diff --git a/tests/addr.rs b/tests/addr.rs index 027c8292f..aada557c3 100644 --- a/tests/addr.rs +++ b/tests/addr.rs @@ -3,7 +3,11 @@ use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; use async_std::net::ToSocketAddrs; use async_std::task; -fn blocking_resolve(a: A) -> Result, String> { +fn blocking_resolve(a: A) -> Result, String> +where + A: ToSocketAddrs, + A::Iter: Send, +{ let socket_addrs = task::block_on(a.to_socket_addrs()); match socket_addrs { Ok(a) => Ok(a.collect()), From 6db0085596b4ce402ffec203e229fac8723a1f99 Mon Sep 17 00:00:00 2001 From: DCjanus Date: Thu, 5 Sep 2019 01:12:17 +0800 Subject: [PATCH 14/14] lifetime for future --- src/net/addr.rs | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/net/addr.rs b/src/net/addr.rs index f3dc605da..39dba52df 100644 --- a/src/net/addr.rs +++ b/src/net/addr.rs @@ -9,18 +9,19 @@ use crate::future::Future; use crate::io; use crate::task::blocking; use crate::task::{Context, Poll}; +use std::marker::PhantomData; cfg_if! { if #[cfg(feature = "docs")] { #[doc(hidden)] - pub struct ImplFuture(std::marker::PhantomData); + pub struct ImplFuture<'a, T>(std::marker::PhantomData<&'a T>); macro_rules! ret { - ($f:tt, $i:ty) => (ImplFuture>); + ($a:lifetime, $f:tt, $i:ty) => (ImplFuture<$a, io::Result<$i>>); } } else { macro_rules! ret { - ($f:tt, $i:ty) => ($f<$i>); + ($a:lifetime, $f:tt, $i:ty) => ($f<$a, $i>); } } } @@ -41,23 +42,25 @@ pub trait ToSocketAddrs { /// resolution performed. /// /// Note that this function may block a backend thread while resolution is performed. - fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter); + fn to_socket_addrs(&self) -> ret!('_, ToSocketAddrsFuture, Self::Iter); } #[doc(hidden)] #[allow(missing_debug_implementations)] -pub enum ToSocketAddrsFuture> { +pub enum ToSocketAddrsFuture<'a, I: Iterator> { + Phantom(PhantomData<&'a ()>), Join(blocking::JoinHandle>), Ready(Ready>), } -impl> Future for ToSocketAddrsFuture { +impl> Future for ToSocketAddrsFuture<'_, I> { type Output = io::Result; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { match self.get_mut() { ToSocketAddrsFuture::Join(f) => Pin::new(&mut *f).poll(cx), ToSocketAddrsFuture::Ready(f) => Pin::new(&mut *f).poll(cx), + _ => unreachable!(), } } } @@ -65,7 +68,7 @@ impl> Future for ToSocketAddrsFuture { impl ToSocketAddrs for SocketAddr { type Iter = std::option::IntoIter; - fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + fn to_socket_addrs(&self) -> ret!('_, ToSocketAddrsFuture, Self::Iter) { ToSocketAddrsFuture::Ready(ready(std::net::ToSocketAddrs::to_socket_addrs(self))) } } @@ -73,7 +76,7 @@ impl ToSocketAddrs for SocketAddr { impl ToSocketAddrs for SocketAddrV4 { type Iter = std::option::IntoIter; - fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + fn to_socket_addrs(&self) -> ret!('_, ToSocketAddrsFuture, Self::Iter) { ToSocketAddrsFuture::Ready(ready(std::net::ToSocketAddrs::to_socket_addrs(self))) } } @@ -81,7 +84,7 @@ impl ToSocketAddrs for SocketAddrV4 { impl ToSocketAddrs for SocketAddrV6 { type Iter = std::option::IntoIter; - fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + fn to_socket_addrs(&self) -> ret!('_, ToSocketAddrsFuture, Self::Iter) { ToSocketAddrsFuture::Ready(ready(std::net::ToSocketAddrs::to_socket_addrs(self))) } } @@ -89,7 +92,7 @@ impl ToSocketAddrs for SocketAddrV6 { impl ToSocketAddrs for (IpAddr, u16) { type Iter = std::option::IntoIter; - fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + fn to_socket_addrs(&self) -> ret!('_, ToSocketAddrsFuture, Self::Iter) { ToSocketAddrsFuture::Ready(ready(std::net::ToSocketAddrs::to_socket_addrs(self))) } } @@ -97,7 +100,7 @@ impl ToSocketAddrs for (IpAddr, u16) { impl ToSocketAddrs for (Ipv4Addr, u16) { type Iter = std::option::IntoIter; - fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + fn to_socket_addrs(&self) -> ret!('_, ToSocketAddrsFuture, Self::Iter) { ToSocketAddrsFuture::Ready(ready(std::net::ToSocketAddrs::to_socket_addrs(self))) } } @@ -105,7 +108,7 @@ impl ToSocketAddrs for (Ipv4Addr, u16) { impl ToSocketAddrs for (Ipv6Addr, u16) { type Iter = std::option::IntoIter; - fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + fn to_socket_addrs(&self) -> ret!('_, ToSocketAddrsFuture, Self::Iter) { ToSocketAddrsFuture::Ready(ready(std::net::ToSocketAddrs::to_socket_addrs(self))) } } @@ -113,7 +116,7 @@ impl ToSocketAddrs for (Ipv6Addr, u16) { impl ToSocketAddrs for (&str, u16) { type Iter = std::vec::IntoIter; - fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + fn to_socket_addrs(&self) -> ret!('_, ToSocketAddrsFuture, Self::Iter) { let host = self.0.to_string(); let port = self.1; let join = blocking::spawn(async move { @@ -126,7 +129,7 @@ impl ToSocketAddrs for (&str, u16) { impl ToSocketAddrs for str { type Iter = std::vec::IntoIter; - fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + fn to_socket_addrs(&self) -> ret!('_, ToSocketAddrsFuture, Self::Iter) { let socket_addrs = self.to_string(); let join = blocking::spawn(async move { std::net::ToSocketAddrs::to_socket_addrs(&socket_addrs) }); @@ -137,7 +140,7 @@ impl ToSocketAddrs for str { impl<'a> ToSocketAddrs for &'a [SocketAddr] { type Iter = std::iter::Cloned>; - fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + fn to_socket_addrs(&self) -> ret!('_, ToSocketAddrsFuture, Self::Iter) { ToSocketAddrsFuture::Ready(ready(std::net::ToSocketAddrs::to_socket_addrs(self))) } } @@ -145,7 +148,7 @@ impl<'a> ToSocketAddrs for &'a [SocketAddr] { impl ToSocketAddrs for &T { type Iter = T::Iter; - fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + fn to_socket_addrs(&self) -> ret!('_, ToSocketAddrsFuture, Self::Iter) { (**self).to_socket_addrs() } } @@ -153,7 +156,7 @@ impl ToSocketAddrs for &T { impl ToSocketAddrs for String { type Iter = std::vec::IntoIter; - fn to_socket_addrs(&self) -> ret!(ToSocketAddrsFuture, Self::Iter) { + fn to_socket_addrs(&self) -> ret!('_, ToSocketAddrsFuture, Self::Iter) { ToSocketAddrs::to_socket_addrs(self.as_str()) } }