1use crate::future;
2
3use std::io;
4use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
5
6pub trait ToSocketAddrs: sealed::ToSocketAddrsPriv {}
23
24type ReadyFuture<T> = future::Ready<io::Result<T>>;
25
26impl<T: ToSocketAddrs + ?Sized> ToSocketAddrs for &T {}
29
30impl<T> sealed::ToSocketAddrsPriv for &T
31where
32 T: sealed::ToSocketAddrsPriv + ?Sized,
33{
34 type Iter = T::Iter;
35 type Future = T::Future;
36
37 fn to_socket_addrs(&self) -> Self::Future {
38 (**self).to_socket_addrs()
39 }
40}
41
42impl ToSocketAddrs for SocketAddr {}
45
46impl sealed::ToSocketAddrsPriv for SocketAddr {
47 type Iter = std::option::IntoIter<SocketAddr>;
48 type Future = ReadyFuture<Self::Iter>;
49
50 fn to_socket_addrs(&self) -> Self::Future {
51 let iter = Some(*self).into_iter();
52 future::ok(iter)
53 }
54}
55
56impl ToSocketAddrs for SocketAddrV4 {}
59
60impl sealed::ToSocketAddrsPriv for SocketAddrV4 {
61 type Iter = std::option::IntoIter<SocketAddr>;
62 type Future = ReadyFuture<Self::Iter>;
63
64 fn to_socket_addrs(&self) -> Self::Future {
65 SocketAddr::V4(*self).to_socket_addrs()
66 }
67}
68
69impl ToSocketAddrs for SocketAddrV6 {}
72
73impl sealed::ToSocketAddrsPriv for SocketAddrV6 {
74 type Iter = std::option::IntoIter<SocketAddr>;
75 type Future = ReadyFuture<Self::Iter>;
76
77 fn to_socket_addrs(&self) -> Self::Future {
78 SocketAddr::V6(*self).to_socket_addrs()
79 }
80}
81
82impl ToSocketAddrs for (IpAddr, u16) {}
85
86impl sealed::ToSocketAddrsPriv for (IpAddr, u16) {
87 type Iter = std::option::IntoIter<SocketAddr>;
88 type Future = ReadyFuture<Self::Iter>;
89
90 fn to_socket_addrs(&self) -> Self::Future {
91 let iter = Some(SocketAddr::from(*self)).into_iter();
92 future::ok(iter)
93 }
94}
95
96impl ToSocketAddrs for (Ipv4Addr, u16) {}
99
100impl sealed::ToSocketAddrsPriv for (Ipv4Addr, u16) {
101 type Iter = std::option::IntoIter<SocketAddr>;
102 type Future = ReadyFuture<Self::Iter>;
103
104 fn to_socket_addrs(&self) -> Self::Future {
105 let (ip, port) = *self;
106 SocketAddrV4::new(ip, port).to_socket_addrs()
107 }
108}
109
110impl ToSocketAddrs for (Ipv6Addr, u16) {}
113
114impl sealed::ToSocketAddrsPriv for (Ipv6Addr, u16) {
115 type Iter = std::option::IntoIter<SocketAddr>;
116 type Future = ReadyFuture<Self::Iter>;
117
118 fn to_socket_addrs(&self) -> Self::Future {
119 let (ip, port) = *self;
120 SocketAddrV6::new(ip, port, 0, 0).to_socket_addrs()
121 }
122}
123
124cfg_dns! {
125 impl ToSocketAddrs for str {}
128
129 impl sealed::ToSocketAddrsPriv for str {
130 type Iter = sealed::OneOrMore;
131 type Future = sealed::MaybeReady;
132
133 fn to_socket_addrs(&self) -> Self::Future {
134 use crate::runtime::spawn_blocking;
135 use sealed::MaybeReady;
136
137 let res: Result<SocketAddr, _> = self.parse();
139
140 if let Ok(addr) = res {
141 return MaybeReady::Ready(Some(addr));
142 }
143
144 let s = self.to_owned();
146
147 MaybeReady::Blocking(spawn_blocking(move || {
148 std::net::ToSocketAddrs::to_socket_addrs(&s)
149 }))
150 }
151 }
152
153 impl ToSocketAddrs for (&str, u16) {}
156
157 impl sealed::ToSocketAddrsPriv for (&str, u16) {
158 type Iter = sealed::OneOrMore;
159 type Future = sealed::MaybeReady;
160
161 fn to_socket_addrs(&self) -> Self::Future {
162 use crate::runtime::spawn_blocking;
163 use sealed::MaybeReady;
164
165 let (host, port) = *self;
166
167 if let Ok(addr) = host.parse::<Ipv4Addr>() {
169 let addr = SocketAddrV4::new(addr, port);
170 let addr = SocketAddr::V4(addr);
171
172 return MaybeReady::Ready(Some(addr));
173 }
174
175 if let Ok(addr) = host.parse::<Ipv6Addr>() {
176 let addr = SocketAddrV6::new(addr, port, 0, 0);
177 let addr = SocketAddr::V6(addr);
178
179 return MaybeReady::Ready(Some(addr));
180 }
181
182 let host = host.to_owned();
183
184 MaybeReady::Blocking(spawn_blocking(move || {
185 std::net::ToSocketAddrs::to_socket_addrs(&(&host[..], port))
186 }))
187 }
188 }
189
190 impl ToSocketAddrs for String {}
193
194 impl sealed::ToSocketAddrsPriv for String {
195 type Iter = <str as sealed::ToSocketAddrsPriv>::Iter;
196 type Future = <str as sealed::ToSocketAddrsPriv>::Future;
197
198 fn to_socket_addrs(&self) -> Self::Future {
199 (&self[..]).to_socket_addrs()
200 }
201 }
202}
203
204pub(crate) mod sealed {
205 use std::future::Future;
210 use std::io;
211 use std::net::SocketAddr;
212
213 cfg_dns! {
214 use crate::task::JoinHandle;
215
216 use std::option;
217 use std::pin::Pin;
218 use std::task::{Context, Poll};
219 use std::vec;
220 }
221
222 #[doc(hidden)]
223 pub trait ToSocketAddrsPriv {
224 type Iter: Iterator<Item = SocketAddr> + Send + 'static;
225 type Future: Future<Output = io::Result<Self::Iter>> + Send + 'static;
226
227 fn to_socket_addrs(&self) -> Self::Future;
228 }
229
230 cfg_dns! {
231 #[doc(hidden)]
232 #[derive(Debug)]
233 pub enum MaybeReady {
234 Ready(Option<SocketAddr>),
235 Blocking(JoinHandle<io::Result<vec::IntoIter<SocketAddr>>>),
236 }
237
238 #[doc(hidden)]
239 #[derive(Debug)]
240 pub enum OneOrMore {
241 One(option::IntoIter<SocketAddr>),
242 More(vec::IntoIter<SocketAddr>),
243 }
244
245 impl Future for MaybeReady {
246 type Output = io::Result<OneOrMore>;
247
248 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
249 match *self {
250 MaybeReady::Ready(ref mut i) => {
251 let iter = OneOrMore::One(i.take().into_iter());
252 Poll::Ready(Ok(iter))
253 }
254 MaybeReady::Blocking(ref mut rx) => {
255 let res = ready!(Pin::new(rx).poll(cx))?.map(OneOrMore::More);
256
257 Poll::Ready(res)
258 }
259 }
260 }
261 }
262
263 impl Iterator for OneOrMore {
264 type Item = SocketAddr;
265
266 fn next(&mut self) -> Option<Self::Item> {
267 match self {
268 OneOrMore::One(i) => i.next(),
269 OneOrMore::More(i) => i.next(),
270 }
271 }
272
273 fn size_hint(&self) -> (usize, Option<usize>) {
274 match self {
275 OneOrMore::One(i) => i.size_hint(),
276 OneOrMore::More(i) => i.size_hint(),
277 }
278 }
279 }
280 }
281}