1use std::future;
2use std::io;
3use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
4
5pub trait ToSocketAddrs: sealed::ToSocketAddrsPriv {}
20
21type ReadyFuture<T> = future::Ready<io::Result<T>>;
22
23cfg_net! {
24 pub(crate) fn to_socket_addrs<T>(arg: T) -> T::Future
25 where
26 T: ToSocketAddrs,
27 {
28 arg.to_socket_addrs(sealed::Internal)
29 }
30}
31
32impl<T: ToSocketAddrs + ?Sized> ToSocketAddrs for &T {}
35
36impl<T> sealed::ToSocketAddrsPriv for &T
37where
38 T: sealed::ToSocketAddrsPriv + ?Sized,
39{
40 type Iter = T::Iter;
41 type Future = T::Future;
42
43 fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
44 (**self).to_socket_addrs(sealed::Internal)
45 }
46}
47
48impl ToSocketAddrs for SocketAddr {}
51
52impl sealed::ToSocketAddrsPriv for SocketAddr {
53 type Iter = std::option::IntoIter<SocketAddr>;
54 type Future = ReadyFuture<Self::Iter>;
55
56 fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
57 let iter = Some(*self).into_iter();
58 future::ready(Ok(iter))
59 }
60}
61
62impl ToSocketAddrs for SocketAddrV4 {}
65
66impl sealed::ToSocketAddrsPriv for SocketAddrV4 {
67 type Iter = std::option::IntoIter<SocketAddr>;
68 type Future = ReadyFuture<Self::Iter>;
69
70 fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
71 SocketAddr::V4(*self).to_socket_addrs(sealed::Internal)
72 }
73}
74
75impl ToSocketAddrs for SocketAddrV6 {}
78
79impl sealed::ToSocketAddrsPriv for SocketAddrV6 {
80 type Iter = std::option::IntoIter<SocketAddr>;
81 type Future = ReadyFuture<Self::Iter>;
82
83 fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
84 SocketAddr::V6(*self).to_socket_addrs(sealed::Internal)
85 }
86}
87
88impl ToSocketAddrs for (IpAddr, u16) {}
91
92impl sealed::ToSocketAddrsPriv for (IpAddr, u16) {
93 type Iter = std::option::IntoIter<SocketAddr>;
94 type Future = ReadyFuture<Self::Iter>;
95
96 fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
97 let iter = Some(SocketAddr::from(*self)).into_iter();
98 future::ready(Ok(iter))
99 }
100}
101
102impl ToSocketAddrs for (Ipv4Addr, u16) {}
105
106impl sealed::ToSocketAddrsPriv for (Ipv4Addr, u16) {
107 type Iter = std::option::IntoIter<SocketAddr>;
108 type Future = ReadyFuture<Self::Iter>;
109
110 fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
111 let (ip, port) = *self;
112 SocketAddrV4::new(ip, port).to_socket_addrs(sealed::Internal)
113 }
114}
115
116impl ToSocketAddrs for (Ipv6Addr, u16) {}
119
120impl sealed::ToSocketAddrsPriv for (Ipv6Addr, u16) {
121 type Iter = std::option::IntoIter<SocketAddr>;
122 type Future = ReadyFuture<Self::Iter>;
123
124 fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
125 let (ip, port) = *self;
126 SocketAddrV6::new(ip, port, 0, 0).to_socket_addrs(sealed::Internal)
127 }
128}
129
130impl ToSocketAddrs for &[SocketAddr] {}
133
134impl sealed::ToSocketAddrsPriv for &[SocketAddr] {
135 type Iter = std::vec::IntoIter<SocketAddr>;
136 type Future = ReadyFuture<Self::Iter>;
137
138 fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
139 #[inline]
140 fn slice_to_vec(addrs: &[SocketAddr]) -> Vec<SocketAddr> {
141 addrs.to_vec()
142 }
143
144 let iter = slice_to_vec(self).into_iter();
155 future::ready(Ok(iter))
156 }
157}
158
159cfg_net! {
160 impl ToSocketAddrs for str {}
163
164 impl sealed::ToSocketAddrsPriv for str {
165 type Iter = sealed::OneOrMore;
166 type Future = sealed::MaybeReady;
167
168 fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
169 use crate::blocking::spawn_blocking;
170 use sealed::MaybeReady;
171
172 let res: Result<SocketAddr, _> = self.parse();
174
175 if let Ok(addr) = res {
176 return MaybeReady(sealed::State::Ready(Some(addr)));
177 }
178
179 let s = self.to_owned();
181
182 MaybeReady(sealed::State::Blocking(spawn_blocking(move || {
183 std::net::ToSocketAddrs::to_socket_addrs(&s)
184 })))
185 }
186 }
187
188 impl ToSocketAddrs for (&str, u16) {}
191
192 impl sealed::ToSocketAddrsPriv for (&str, u16) {
193 type Iter = sealed::OneOrMore;
194 type Future = sealed::MaybeReady;
195
196 fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
197 use crate::blocking::spawn_blocking;
198 use sealed::MaybeReady;
199
200 let (host, port) = *self;
201
202 if let Ok(addr) = host.parse::<Ipv4Addr>() {
204 let addr = SocketAddrV4::new(addr, port);
205 let addr = SocketAddr::V4(addr);
206
207 return MaybeReady(sealed::State::Ready(Some(addr)));
208 }
209
210 if let Ok(addr) = host.parse::<Ipv6Addr>() {
211 let addr = SocketAddrV6::new(addr, port, 0, 0);
212 let addr = SocketAddr::V6(addr);
213
214 return MaybeReady(sealed::State::Ready(Some(addr)));
215 }
216
217 let host = host.to_owned();
218
219 MaybeReady(sealed::State::Blocking(spawn_blocking(move || {
220 std::net::ToSocketAddrs::to_socket_addrs(&(&host[..], port))
221 })))
222 }
223 }
224
225 impl ToSocketAddrs for (String, u16) {}
228
229 impl sealed::ToSocketAddrsPriv for (String, u16) {
230 type Iter = sealed::OneOrMore;
231 type Future = sealed::MaybeReady;
232
233 fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
234 (self.0.as_str(), self.1).to_socket_addrs(sealed::Internal)
235 }
236 }
237
238 impl ToSocketAddrs for String {}
241
242 impl sealed::ToSocketAddrsPriv for String {
243 type Iter = <str as sealed::ToSocketAddrsPriv>::Iter;
244 type Future = <str as sealed::ToSocketAddrsPriv>::Future;
245
246 fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
247 self[..].to_socket_addrs(sealed::Internal)
248 }
249 }
250}
251
252pub(crate) mod sealed {
253 use std::future::Future;
258 use std::io;
259 use std::net::SocketAddr;
260
261 #[doc(hidden)]
262 pub trait ToSocketAddrsPriv {
263 type Iter: Iterator<Item = SocketAddr> + Send + 'static;
264 type Future: Future<Output = io::Result<Self::Iter>> + Send + 'static;
265
266 fn to_socket_addrs(&self, internal: Internal) -> Self::Future;
267 }
268
269 #[allow(missing_debug_implementations)]
270 pub struct Internal;
271
272 cfg_net! {
273 use crate::blocking::JoinHandle;
274
275 use std::option;
276 use std::pin::Pin;
277 use std::task::{ready,Context, Poll};
278 use std::vec;
279
280 #[doc(hidden)]
281 #[derive(Debug)]
282 pub struct MaybeReady(pub(super) State);
283
284 #[derive(Debug)]
285 pub(super) enum State {
286 Ready(Option<SocketAddr>),
287 Blocking(JoinHandle<io::Result<vec::IntoIter<SocketAddr>>>),
288 }
289
290 #[doc(hidden)]
291 #[derive(Debug)]
292 pub enum OneOrMore {
293 One(option::IntoIter<SocketAddr>),
294 More(vec::IntoIter<SocketAddr>),
295 }
296
297 impl Future for MaybeReady {
298 type Output = io::Result<OneOrMore>;
299
300 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
301 match self.0 {
302 State::Ready(ref mut i) => {
303 let iter = OneOrMore::One(i.take().into_iter());
304 Poll::Ready(Ok(iter))
305 }
306 State::Blocking(ref mut rx) => {
307 let res = ready!(Pin::new(rx).poll(cx))?.map(OneOrMore::More);
308
309 Poll::Ready(res)
310 }
311 }
312 }
313 }
314
315 impl Iterator for OneOrMore {
316 type Item = SocketAddr;
317
318 fn next(&mut self) -> Option<Self::Item> {
319 match self {
320 OneOrMore::One(i) => i.next(),
321 OneOrMore::More(i) => i.next(),
322 }
323 }
324
325 fn size_hint(&self) -> (usize, Option<usize>) {
326 match self {
327 OneOrMore::One(i) => i.size_hint(),
328 OneOrMore::More(i) => i.size_hint(),
329 }
330 }
331 }
332 }
333}