1use std::fmt;
2use std::future::Future;
3use std::io;
4use std::mem;
5use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
6use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
7use std::pin::Pin;
8use std::task::{Context, Poll};
9
10use blocking::unblock;
11use futures_lite::future;
12
13/// Converts or resolves addresses to [`SocketAddr`] values.
14///
15/// This trait currently only appears in function signatures and cannot be used directly.
16///
17/// However, you can use the [`resolve()`][`super::resolve()`] function to resolve addresses.
18pub trait AsyncToSocketAddrs: Sealed {}
19
20pub trait Sealed {
21 /// Returned iterator over socket addresses which this type may correspond to.
22 type Iter: Iterator<Item = SocketAddr> + Unpin;
23
24 /// Converts this object to an iterator of resolved `SocketAddr`s.
25 ///
26 /// The returned iterator may not actually yield any values depending on the outcome of any
27 /// resolution performed.
28 ///
29 /// Note that this function may block a backend thread while resolution is performed.
30 fn to_socket_addrs(&self) -> ToSocketAddrsFuture<Self::Iter>;
31}
32
33pub enum ToSocketAddrsFuture<I> {
34 Resolving(future::Boxed<io::Result<I>>),
35 Ready(io::Result<I>),
36 Done,
37}
38
39impl<I> fmt::Debug for ToSocketAddrsFuture<I> {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 write!(f, "ToSocketAddrsFuture")
42 }
43}
44
45impl<I: Iterator<Item = SocketAddr> + Unpin> Future for ToSocketAddrsFuture<I> {
46 type Output = io::Result<I>;
47
48 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
49 let state: ToSocketAddrsFuture = mem::replace(&mut *self, src:ToSocketAddrsFuture::Done);
50
51 match state {
52 ToSocketAddrsFuture::Resolving(mut task: Pin + Send>>) => {
53 let poll: Poll> = Pin::new(&mut task).poll(cx);
54 if poll.is_pending() {
55 *self = ToSocketAddrsFuture::Resolving(task);
56 }
57 poll
58 }
59 ToSocketAddrsFuture::Ready(res: Result) => Poll::Ready(res),
60 ToSocketAddrsFuture::Done => panic!("polled a completed future"),
61 }
62 }
63}
64
65impl AsyncToSocketAddrs for SocketAddr {}
66
67impl Sealed for SocketAddr {
68 type Iter = std::option::IntoIter<SocketAddr>;
69
70 fn to_socket_addrs(&self) -> ToSocketAddrsFuture<Self::Iter> {
71 ToSocketAddrsFuture::Ready(Ok(Some(*self).into_iter()))
72 }
73}
74
75impl AsyncToSocketAddrs for SocketAddrV4 {}
76
77impl Sealed for SocketAddrV4 {
78 type Iter = std::option::IntoIter<SocketAddr>;
79
80 fn to_socket_addrs(&self) -> ToSocketAddrsFuture<Self::Iter> {
81 Sealed::to_socket_addrs(&SocketAddr::V4(*self))
82 }
83}
84
85impl AsyncToSocketAddrs for SocketAddrV6 {}
86
87impl Sealed for SocketAddrV6 {
88 type Iter = std::option::IntoIter<SocketAddr>;
89
90 fn to_socket_addrs(&self) -> ToSocketAddrsFuture<Self::Iter> {
91 Sealed::to_socket_addrs(&SocketAddr::V6(*self))
92 }
93}
94
95impl AsyncToSocketAddrs for (IpAddr, u16) {}
96
97impl Sealed for (IpAddr, u16) {
98 type Iter = std::option::IntoIter<SocketAddr>;
99
100 fn to_socket_addrs(&self) -> ToSocketAddrsFuture<Self::Iter> {
101 let (ip: IpAddr, port: u16) = *self;
102 match ip {
103 IpAddr::V4(a: Ipv4Addr) => Sealed::to_socket_addrs(&(a, port)),
104 IpAddr::V6(a: Ipv6Addr) => Sealed::to_socket_addrs(&(a, port)),
105 }
106 }
107}
108
109impl AsyncToSocketAddrs for (Ipv4Addr, u16) {}
110
111impl Sealed for (Ipv4Addr, u16) {
112 type Iter = std::option::IntoIter<SocketAddr>;
113
114 fn to_socket_addrs(&self) -> ToSocketAddrsFuture<Self::Iter> {
115 let (ip: Ipv4Addr, port: u16) = *self;
116 Sealed::to_socket_addrs(&SocketAddrV4::new(ip, port))
117 }
118}
119
120impl AsyncToSocketAddrs for (Ipv6Addr, u16) {}
121
122impl Sealed for (Ipv6Addr, u16) {
123 type Iter = std::option::IntoIter<SocketAddr>;
124
125 fn to_socket_addrs(&self) -> ToSocketAddrsFuture<Self::Iter> {
126 let (ip: Ipv6Addr, port: u16) = *self;
127 Sealed::to_socket_addrs(&SocketAddrV6::new(ip, port, flowinfo:0, scope_id:0))
128 }
129}
130
131impl AsyncToSocketAddrs for (&str, u16) {}
132
133impl Sealed for (&str, u16) {
134 type Iter = std::vec::IntoIter<SocketAddr>;
135
136 fn to_socket_addrs(&self) -> ToSocketAddrsFuture<Self::Iter> {
137 let (host: &str, port: u16) = *self;
138
139 if let Ok(addr: Ipv4Addr) = host.parse::<Ipv4Addr>() {
140 let addr: SocketAddrV4 = SocketAddrV4::new(ip:addr, port);
141 return ToSocketAddrsFuture::Ready(Ok(vec![SocketAddr::V4(addr)].into_iter()));
142 }
143
144 if let Ok(addr: Ipv6Addr) = host.parse::<Ipv6Addr>() {
145 let addr: SocketAddrV6 = SocketAddrV6::new(ip:addr, port, flowinfo:0, scope_id:0);
146 return ToSocketAddrsFuture::Ready(Ok(vec![SocketAddr::V6(addr)].into_iter()));
147 }
148
149 let host: String = host.to_string();
150 let future: Task, …>> = unblock(move || {
151 let addr: (&str, u16) = (host.as_str(), port);
152 ToSocketAddrs::to_socket_addrs(&addr)
153 });
154 ToSocketAddrsFuture::Resolving(Box::pin(future))
155 }
156}
157
158impl AsyncToSocketAddrs for (String, u16) {}
159
160impl Sealed for (String, u16) {
161 type Iter = std::vec::IntoIter<SocketAddr>;
162
163 fn to_socket_addrs(&self) -> ToSocketAddrsFuture<Self::Iter> {
164 Sealed::to_socket_addrs(&(&*self.0, self.1))
165 }
166}
167
168impl AsyncToSocketAddrs for str {}
169
170impl Sealed for str {
171 type Iter = std::vec::IntoIter<SocketAddr>;
172
173 fn to_socket_addrs(&self) -> ToSocketAddrsFuture<Self::Iter> {
174 if let Ok(addr: SocketAddr) = self.parse() {
175 return ToSocketAddrsFuture::Ready(Ok(vec![addr].into_iter()));
176 }
177
178 let addr: String = self.to_string();
179 let future: Task, …>> = unblock(move || std::net::ToSocketAddrs::to_socket_addrs(self:addr.as_str()));
180 ToSocketAddrsFuture::Resolving(Box::pin(future))
181 }
182}
183
184impl AsyncToSocketAddrs for &[SocketAddr] {}
185
186impl<'a> Sealed for &'a [SocketAddr] {
187 type Iter = std::iter::Cloned<std::slice::Iter<'a, SocketAddr>>;
188
189 fn to_socket_addrs(&self) -> ToSocketAddrsFuture<Self::Iter> {
190 ToSocketAddrsFuture::Ready(Ok(self.iter().cloned()))
191 }
192}
193
194impl<T: AsyncToSocketAddrs + ?Sized> AsyncToSocketAddrs for &T {}
195
196impl<T: Sealed + ?Sized> Sealed for &T {
197 type Iter = T::Iter;
198
199 fn to_socket_addrs(&self) -> ToSocketAddrsFuture<Self::Iter> {
200 Sealed::to_socket_addrs(&**self)
201 }
202}
203
204impl AsyncToSocketAddrs for String {}
205
206impl Sealed for String {
207 type Iter = std::vec::IntoIter<SocketAddr>;
208
209 fn to_socket_addrs(&self) -> ToSocketAddrsFuture<Self::Iter> {
210 Sealed::to_socket_addrs(&**self)
211 }
212}
213