From 5ac0c359aa6c7d6aee57f3ffd25a762a81594314 Mon Sep 17 00:00:00 2001 From: EOF <18029203+eof228@users.noreply.github.com> Date: Sun, 19 Jun 2022 15:25:33 +0300 Subject: [PATCH] Rework ToSocketAddrs::to_socket_addrs - Change return type to Pin>> --- src/net/addr.rs | 207 +++++++++++++----------------------------------- 1 file changed, 55 insertions(+), 152 deletions(-) diff --git a/src/net/addr.rs b/src/net/addr.rs index 71988fb3..be189d30 100644 --- a/src/net/addr.rs +++ b/src/net/addr.rs @@ -1,28 +1,13 @@ +use std::future; use std::future::Future; -use std::mem; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6}; use std::pin::Pin; use crate::io; -use crate::task::{spawn_blocking, Context, JoinHandle, Poll}; +use crate::task::{spawn_blocking}; use crate::utils::Context as ErrorContext; -cfg_not_docs! { - macro_rules! ret { - (impl Future, $fut:ty) => ($fut); - } -} - -cfg_docs! { - #[doc(hidden)] - pub struct ImplFuture(std::marker::PhantomData); - - macro_rules! ret { - (impl Future, $fut:ty) => (ImplFuture<$out>); - } -} - /// Converts or resolves addresses to [`SocketAddr`] values. /// /// This trait is an async version of [`std::net::ToSocketAddrs`]. @@ -52,114 +37,51 @@ pub trait ToSocketAddrs { /// resolution performed. /// /// Note that this function may block a backend thread while resolution is performed. - fn to_socket_addrs( - &self, - ) -> ret!( - impl Future, - ToSocketAddrsFuture - ); -} - -#[doc(hidden)] -#[allow(missing_debug_implementations)] -pub enum ToSocketAddrsFuture { - Resolving(JoinHandle>), - Ready(io::Result), - Done, -} - -// The field of `Self::Resolving` is `Unpin`, and the field of `Self::Ready` is never pinned. -impl Unpin for ToSocketAddrsFuture {} - -/// Wrap `std::io::Error` with additional message -/// -/// Keeps the original error kind and stores the original I/O error as `source`. -impl ErrorContext for ToSocketAddrsFuture { - fn context(self, message: impl Fn() -> String) -> Self { - match self { - ToSocketAddrsFuture::Ready(res) => ToSocketAddrsFuture::Ready(res.context(message)), - x => x, - } - } -} - -impl> Future for ToSocketAddrsFuture { - type Output = io::Result; - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let this = self.get_mut(); - let state = mem::replace(this, ToSocketAddrsFuture::Done); - - match state { - ToSocketAddrsFuture::Resolving(mut task) => { - let poll = Pin::new(&mut task).poll(cx); - if poll.is_pending() { - *this = ToSocketAddrsFuture::Resolving(task); - } - poll - } - ToSocketAddrsFuture::Ready(res) => Poll::Ready(res), - ToSocketAddrsFuture::Done => panic!("polled a completed future"), - } - } + fn to_socket_addrs<'a>( + &'a self, + ) -> Pin> + 'a>>; } impl ToSocketAddrs for SocketAddr { type Iter = std::option::IntoIter; - fn to_socket_addrs( - &self, - ) -> ret!( - impl Future, - ToSocketAddrsFuture - ) { - ToSocketAddrsFuture::Ready(Ok(Some(*self).into_iter())) + fn to_socket_addrs<'a>( + &'a self, + ) -> Pin> + 'a>> { + Box::pin(future::ready(Ok(Some(*self).into_iter()))) } } impl ToSocketAddrs for SocketAddrV4 { type Iter = std::option::IntoIter; - fn to_socket_addrs( - &self, - ) -> ret!( - impl Future, - ToSocketAddrsFuture - ) { - SocketAddr::V4(*self) - .to_socket_addrs() - .context(|| format!("could not resolve address `{}`", self)) + fn to_socket_addrs<'a>( + &'a self, + ) -> Pin> + 'a>> { + Box::pin(future::ready(Ok(Some(SocketAddr::V4(*self)).into_iter()))) } } impl ToSocketAddrs for SocketAddrV6 { type Iter = std::option::IntoIter; - fn to_socket_addrs( - &self, - ) -> ret!( - impl Future, - ToSocketAddrsFuture - ) { - SocketAddr::V6(*self) - .to_socket_addrs() - .context(|| format!("could not resolve address `{}`", self)) + fn to_socket_addrs<'a>( + &'a self, + ) -> Pin> + 'a>> { + Box::pin(future::ready(Ok(Some(SocketAddr::V6(*self)).into_iter()))) } } impl ToSocketAddrs for (IpAddr, u16) { type Iter = std::option::IntoIter; - fn to_socket_addrs( - &self, - ) -> ret!( - impl Future, - ToSocketAddrsFuture - ) { + fn to_socket_addrs<'a>( + &'a self, + ) -> Pin> + 'a>> { let (ip, port) = *self; match ip { - IpAddr::V4(a) => (a, port).to_socket_addrs(), - IpAddr::V6(a) => (a, port).to_socket_addrs(), + IpAddr::V4(a) => Box::pin(future::ready(Ok(Some(SocketAddr::V4(SocketAddrV4::new(a, port))).into_iter()))), + IpAddr::V6(a) => Box::pin(future::ready(Ok(Some(SocketAddr::V6(SocketAddrV6::new(a, port, 0, 0))).into_iter()))), } } } @@ -167,50 +89,41 @@ impl ToSocketAddrs for (IpAddr, u16) { impl ToSocketAddrs for (Ipv4Addr, u16) { type Iter = std::option::IntoIter; - fn to_socket_addrs( - &self, - ) -> ret!( - impl Future, - ToSocketAddrsFuture - ) { + fn to_socket_addrs<'a>( + &'a self, + ) -> Pin> + 'a>> { let (ip, port) = *self; - SocketAddrV4::new(ip, port).to_socket_addrs() + Box::pin(future::ready(Ok(Some(SocketAddr::V4(SocketAddrV4::new(ip, port))).into_iter()))) } } impl ToSocketAddrs for (Ipv6Addr, u16) { type Iter = std::option::IntoIter; - fn to_socket_addrs( - &self, - ) -> ret!( - impl Future, - ToSocketAddrsFuture - ) { + fn to_socket_addrs<'a>( + &'a self, + ) -> Pin> + 'a>> { let (ip, port) = *self; - SocketAddrV6::new(ip, port, 0, 0).to_socket_addrs() + Box::pin(future::ready(Ok(Some(SocketAddr::V6(SocketAddrV6::new(ip, port, 0, 0))).into_iter()))) } } impl ToSocketAddrs for (&str, u16) { type Iter = std::vec::IntoIter; - fn to_socket_addrs( - &self, - ) -> ret!( - impl Future, - ToSocketAddrsFuture - ) { + fn to_socket_addrs<'a>( + &'a self, + ) -> Pin> + 'a>> { let (host, port) = *self; if let Ok(addr) = host.parse::() { let addr = SocketAddrV4::new(addr, port); - return ToSocketAddrsFuture::Ready(Ok(vec![SocketAddr::V4(addr)].into_iter())); + return Box::pin(future::ready(Ok(vec![SocketAddr::V4(addr)].into_iter()))); } if let Ok(addr) = host.parse::() { let addr = SocketAddrV6::new(addr, port, 0, 0); - return ToSocketAddrsFuture::Ready(Ok(vec![SocketAddr::V6(addr)].into_iter())); + return Box::pin(future::ready(Ok(vec![SocketAddr::V6(addr)].into_iter()))); } let host = host.to_string(); @@ -219,21 +132,19 @@ impl ToSocketAddrs for (&str, u16) { std::net::ToSocketAddrs::to_socket_addrs(&addr) .context(|| format!("could not resolve address `{:?}`", addr)) }); - ToSocketAddrsFuture::Resolving(task) + + Box::pin(task) } } impl ToSocketAddrs for str { type Iter = std::vec::IntoIter; - fn to_socket_addrs( - &self, - ) -> ret!( - impl Future, - ToSocketAddrsFuture - ) { + fn to_socket_addrs<'a>( + &'a self, + ) -> Pin> + 'a>> { if let Ok(addr) = self.parse() { - return ToSocketAddrsFuture::Ready(Ok(vec![addr].into_iter())); + return Box::pin(future::ready(Ok(vec![addr].into_iter()))); } let addr = self.to_string(); @@ -241,32 +152,27 @@ impl ToSocketAddrs for str { std::net::ToSocketAddrs::to_socket_addrs(addr.as_str()) .context(|| format!("could not resolve address `{:?}`", addr)) }); - ToSocketAddrsFuture::Resolving(task) + + Box::pin(task) } } -impl<'a> ToSocketAddrs for &'a [SocketAddr] { - type Iter = std::iter::Cloned>; +impl<'b> ToSocketAddrs for &'b [SocketAddr] { + type Iter = std::iter::Cloned>; - fn to_socket_addrs( - &self, - ) -> ret!( - impl Future, - ToSocketAddrsFuture - ) { - ToSocketAddrsFuture::Ready(Ok(self.iter().cloned())) + fn to_socket_addrs<'a>( + &'a self, + ) -> Pin> + 'a>> { + Box::pin(future::ready(Ok(self.iter().cloned()))) } } impl ToSocketAddrs for &T { type Iter = T::Iter; - fn to_socket_addrs( - &self, - ) -> ret!( - impl Future, - ToSocketAddrsFuture - ) { + fn to_socket_addrs<'a>( + &'a self, + ) -> Pin> + 'a>> { (**self).to_socket_addrs() } } @@ -274,12 +180,9 @@ impl ToSocketAddrs for &T { impl ToSocketAddrs for String { type Iter = std::vec::IntoIter; - fn to_socket_addrs( - &self, - ) -> ret!( - impl Future, - ToSocketAddrsFuture - ) { + fn to_socket_addrs<'a>( + &'a self, + ) -> Pin> + 'a>> { (&**self).to_socket_addrs() } }