1use std::future::Future;
2use std::mem;
3use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
4use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6};
5use std::pin::Pin;
6
7use crate::io;
8use crate::task::{spawn_blocking, Context, JoinHandle, Poll};
9use crate::utils::Context as ErrorContext;
10
11cfg_not_docs! {
12 macro_rules! ret {
13 (impl Future<Output = $out:ty>, $fut:ty) => ($fut);
14 }
15}
16
17cfg_docs! {
18 #[doc(hidden)]
19 pub struct ImplFuture<T>(std::marker::PhantomData<T>);
20
21 macro_rules! ret {
22 (impl Future<Output = $out:ty>, $fut:ty) => (ImplFuture<$out>);
23 }
24}
25
26pub trait ToSocketAddrs {
46 type Iter: Iterator<Item = SocketAddr>;
48
49 fn to_socket_addrs(
56 &self,
57 ) -> ret!(
58 impl Future<Output = Self::Iter>,
59 ToSocketAddrsFuture<Self::Iter>
60 );
61}
62
63#[doc(hidden)]
64#[allow(missing_debug_implementations)]
65pub enum ToSocketAddrsFuture<I> {
66 Resolving(JoinHandle<io::Result<I>>),
67 Ready(io::Result<I>),
68 Done,
69}
70
71impl<I> Unpin for ToSocketAddrsFuture<I> {}
73
74impl<T> ErrorContext for ToSocketAddrsFuture<T> {
78 fn context(self, message: impl Fn() -> String) -> Self {
79 match self {
80 ToSocketAddrsFuture::Ready(res) => ToSocketAddrsFuture::Ready(res.context(message)),
81 x => x,
82 }
83 }
84}
85
86impl<I: Iterator<Item = SocketAddr>> Future for ToSocketAddrsFuture<I> {
87 type Output = io::Result<I>;
88
89 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
90 let this = self.get_mut();
91 let state = mem::replace(this, ToSocketAddrsFuture::Done);
92
93 match state {
94 ToSocketAddrsFuture::Resolving(mut task) => {
95 let poll = Pin::new(&mut task).poll(cx);
96 if poll.is_pending() {
97 *this = ToSocketAddrsFuture::Resolving(task);
98 }
99 poll
100 }
101 ToSocketAddrsFuture::Ready(res) => Poll::Ready(res),
102 ToSocketAddrsFuture::Done => panic!("polled a completed future"),
103 }
104 }
105}
106
107impl ToSocketAddrs for SocketAddr {
108 type Iter = std::option::IntoIter<SocketAddr>;
109
110 fn to_socket_addrs(
111 &self,
112 ) -> ret!(
113 impl Future<Output = Self::Iter>,
114 ToSocketAddrsFuture<Self::Iter>
115 ) {
116 ToSocketAddrsFuture::Ready(Ok(Some(*self).into_iter()))
117 }
118}
119
120impl ToSocketAddrs for SocketAddrV4 {
121 type Iter = std::option::IntoIter<SocketAddr>;
122
123 fn to_socket_addrs(
124 &self,
125 ) -> ret!(
126 impl Future<Output = Self::Iter>,
127 ToSocketAddrsFuture<Self::Iter>
128 ) {
129 SocketAddr::V4(*self)
130 .to_socket_addrs()
131 .context(|| format!("could not resolve address `{}`", self))
132 }
133}
134
135impl ToSocketAddrs for SocketAddrV6 {
136 type Iter = std::option::IntoIter<SocketAddr>;
137
138 fn to_socket_addrs(
139 &self,
140 ) -> ret!(
141 impl Future<Output = Self::Iter>,
142 ToSocketAddrsFuture<Self::Iter>
143 ) {
144 SocketAddr::V6(*self)
145 .to_socket_addrs()
146 .context(|| format!("could not resolve address `{}`", self))
147 }
148}
149
150impl ToSocketAddrs for (IpAddr, u16) {
151 type Iter = std::option::IntoIter<SocketAddr>;
152
153 fn to_socket_addrs(
154 &self,
155 ) -> ret!(
156 impl Future<Output = Self::Iter>,
157 ToSocketAddrsFuture<Self::Iter>
158 ) {
159 let (ip, port) = *self;
160 match ip {
161 IpAddr::V4(a) => (a, port).to_socket_addrs(),
162 IpAddr::V6(a) => (a, port).to_socket_addrs(),
163 }
164 }
165}
166
167impl ToSocketAddrs for (Ipv4Addr, u16) {
168 type Iter = std::option::IntoIter<SocketAddr>;
169
170 fn to_socket_addrs(
171 &self,
172 ) -> ret!(
173 impl Future<Output = Self::Iter>,
174 ToSocketAddrsFuture<Self::Iter>
175 ) {
176 let (ip, port) = *self;
177 SocketAddrV4::new(ip, port).to_socket_addrs()
178 }
179}
180
181impl ToSocketAddrs for (Ipv6Addr, u16) {
182 type Iter = std::option::IntoIter<SocketAddr>;
183
184 fn to_socket_addrs(
185 &self,
186 ) -> ret!(
187 impl Future<Output = Self::Iter>,
188 ToSocketAddrsFuture<Self::Iter>
189 ) {
190 let (ip, port) = *self;
191 SocketAddrV6::new(ip, port, 0, 0).to_socket_addrs()
192 }
193}
194
195impl ToSocketAddrs for (&str, u16) {
196 type Iter = std::vec::IntoIter<SocketAddr>;
197
198 fn to_socket_addrs(
199 &self,
200 ) -> ret!(
201 impl Future<Output = Self::Iter>,
202 ToSocketAddrsFuture<Self::Iter>
203 ) {
204 let (host, port) = *self;
205
206 if let Ok(addr) = host.parse::<Ipv4Addr>() {
207 let addr = SocketAddrV4::new(addr, port);
208 return ToSocketAddrsFuture::Ready(Ok(vec![SocketAddr::V4(addr)].into_iter()));
209 }
210
211 if let Ok(addr) = host.parse::<Ipv6Addr>() {
212 let addr = SocketAddrV6::new(addr, port, 0, 0);
213 return ToSocketAddrsFuture::Ready(Ok(vec![SocketAddr::V6(addr)].into_iter()));
214 }
215
216 let host = host.to_string();
217 let task = spawn_blocking(move || {
218 let addr = (host.as_str(), port);
219 std::net::ToSocketAddrs::to_socket_addrs(&addr)
220 .context(|| format!("could not resolve address `{:?}`", addr))
221 });
222 ToSocketAddrsFuture::Resolving(task)
223 }
224}
225
226impl ToSocketAddrs for str {
227 type Iter = std::vec::IntoIter<SocketAddr>;
228
229 fn to_socket_addrs(
230 &self,
231 ) -> ret!(
232 impl Future<Output = Self::Iter>,
233 ToSocketAddrsFuture<Self::Iter>
234 ) {
235 if let Ok(addr) = self.parse() {
236 return ToSocketAddrsFuture::Ready(Ok(vec![addr].into_iter()));
237 }
238
239 let addr = self.to_string();
240 let task = spawn_blocking(move || {
241 std::net::ToSocketAddrs::to_socket_addrs(addr.as_str())
242 .context(|| format!("could not resolve address `{:?}`", addr))
243 });
244 ToSocketAddrsFuture::Resolving(task)
245 }
246}
247
248impl<'a> ToSocketAddrs for &'a [SocketAddr] {
249 type Iter = std::iter::Cloned<std::slice::Iter<'a, SocketAddr>>;
250
251 fn to_socket_addrs(
252 &self,
253 ) -> ret!(
254 impl Future<Output = Self::Iter>,
255 ToSocketAddrsFuture<Self::Iter>
256 ) {
257 ToSocketAddrsFuture::Ready(Ok(self.iter().cloned()))
258 }
259}
260
261impl<T: ToSocketAddrs + ?Sized> ToSocketAddrs for &T {
262 type Iter = T::Iter;
263
264 fn to_socket_addrs(
265 &self,
266 ) -> ret!(
267 impl Future<Output = Self::Iter>,
268 ToSocketAddrsFuture<Self::Iter>
269 ) {
270 (**self).to_socket_addrs()
271 }
272}
273
274impl ToSocketAddrs for String {
275 type Iter = std::vec::IntoIter<SocketAddr>;
276
277 fn to_socket_addrs(
278 &self,
279 ) -> ret!(
280 impl Future<Output = Self::Iter>,
281 ToSocketAddrsFuture<Self::Iter>
282 ) {
283 (&**self).to_socket_addrs()
284 }
285}