1use std::future::Future;
2use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
3use std::pin::Pin;
4use std::sync::Arc;
5use std::task::{Context, Poll};
6
7use crate::error::Error;
8use crate::host::HostResults;
9use crate::nameinfo::NameInfoResult;
10use crate::resolver::{Options, Resolver};
11
12#[cfg(cares1_24)]
13use c_ares::AresString;
14
15#[cfg(cares1_29)]
16use c_ares::ServerStateFlags;
17
18#[must_use]
20pub struct CAresFuture<T> {
21 inner: futures_channel::oneshot::Receiver<c_ares::Result<T>>,
22 _resolver: Arc<Resolver>,
23}
24
25impl<T> CAresFuture<T> {
26 fn new(
27 promise: futures_channel::oneshot::Receiver<c_ares::Result<T>>,
28 resolver: Arc<Resolver>,
29 ) -> Self {
30 Self {
31 inner: promise,
32 _resolver: resolver,
33 }
34 }
35
36 fn pin_get_inner(
37 self: Pin<&mut Self>,
38 ) -> Pin<&mut futures_channel::oneshot::Receiver<c_ares::Result<T>>> {
39 unsafe { self.map_unchecked_mut(|s| &mut s.inner) }
40 }
41}
42
43impl<T> Future for CAresFuture<T> {
44 type Output = c_ares::Result<T>;
45
46 fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
47 self.pin_get_inner()
48 .poll(cx)
49 .map(|result| result.unwrap_or(Err(c_ares::Error::ECANCELLED)))
50 }
51}
52
53pub struct FutureResolver {
58 inner: Arc<Resolver>,
59}
60
61macro_rules! futurize {
64 ($resolver:expr, $query:ident, $question:expr) => {{
65 let (sender, receiver) = futures_channel::oneshot::channel();
66 $resolver.$query($question, |result| {
67 let _ = sender.send(result);
68 });
69 let resolver = Arc::clone(&$resolver);
70 CAresFuture::new(receiver, resolver)
71 }};
72}
73
74impl FutureResolver {
75 pub fn new() -> Result<Self, Error> {
77 let options = Options::default();
78 Self::with_options(options)
79 }
80
81 pub fn with_options(options: Options) -> Result<Self, Error> {
83 let inner = Resolver::with_options(options)?;
84 let resolver = Self {
85 inner: Arc::new(inner),
86 };
87 Ok(resolver)
88 }
89
90 #[cfg(cares1_22)]
92 pub fn reinit(&self) -> c_ares::Result<&Self> {
93 self.inner.reinit()?;
94 Ok(self)
95 }
96
97 pub fn set_servers(&self, servers: &[&str]) -> c_ares::Result<&Self> {
103 self.inner.set_servers(servers)?;
104 Ok(self)
105 }
106
107 #[cfg(cares1_24)]
109 pub fn get_servers(&self) -> AresString {
110 self.inner.get_servers()
111 }
112
113 pub fn set_local_ipv4(&self, ipv4: Ipv4Addr) -> &Self {
115 self.inner.set_local_ipv4(ipv4);
116 self
117 }
118
119 pub fn set_local_ipv6(&self, ipv6: &Ipv6Addr) -> &Self {
121 self.inner.set_local_ipv6(ipv6);
122 self
123 }
124
125 pub fn set_local_device(&self, device: &str) -> &Self {
127 self.inner.set_local_device(device);
128 self
129 }
130
131 pub fn set_sortlist(&self, sortlist: &[&str]) -> c_ares::Result<&Self> {
138 self.inner.set_sortlist(sortlist)?;
139 Ok(self)
140 }
141
142 #[cfg(cares1_29)]
150 pub fn set_server_state_callback<F>(&self, callback: F) -> &Self
151 where
152 F: FnMut(&str, bool, ServerStateFlags) + Send + 'static,
153 {
154 self.inner.set_server_state_callback(callback);
155 self
156 }
157
158 pub fn query_a(&self, name: &str) -> CAresFuture<c_ares::AResults> {
160 futurize!(self.inner, query_a, name)
161 }
162
163 pub fn search_a(&self, name: &str) -> CAresFuture<c_ares::AResults> {
165 futurize!(self.inner, search_a, name)
166 }
167
168 pub fn query_aaaa(&self, name: &str) -> CAresFuture<c_ares::AAAAResults> {
170 futurize!(self.inner, query_aaaa, name)
171 }
172
173 pub fn search_aaaa(&self, name: &str) -> CAresFuture<c_ares::AAAAResults> {
175 futurize!(self.inner, search_aaaa, name)
176 }
177
178 #[cfg(cares1_17)]
180 pub fn query_caa(&self, name: &str) -> CAresFuture<c_ares::CAAResults> {
181 futurize!(self.inner, query_caa, name)
182 }
183
184 #[cfg(cares1_17)]
186 pub fn search_caa(&self, name: &str) -> CAresFuture<c_ares::CAAResults> {
187 futurize!(self.inner, search_caa, name)
188 }
189
190 pub fn query_cname(&self, name: &str) -> CAresFuture<c_ares::CNameResults> {
192 futurize!(self.inner, query_cname, name)
193 }
194
195 pub fn search_cname(&self, name: &str) -> CAresFuture<c_ares::CNameResults> {
197 futurize!(self.inner, search_cname, name)
198 }
199
200 pub fn query_mx(&self, name: &str) -> CAresFuture<c_ares::MXResults> {
202 futurize!(self.inner, query_mx, name)
203 }
204
205 pub fn search_mx(&self, name: &str) -> CAresFuture<c_ares::MXResults> {
207 futurize!(self.inner, search_mx, name)
208 }
209
210 pub fn query_naptr(&self, name: &str) -> CAresFuture<c_ares::NAPTRResults> {
212 futurize!(self.inner, query_naptr, name)
213 }
214
215 pub fn search_naptr(&self, name: &str) -> CAresFuture<c_ares::NAPTRResults> {
217 futurize!(self.inner, search_naptr, name)
218 }
219
220 pub fn query_ns(&self, name: &str) -> CAresFuture<c_ares::NSResults> {
222 futurize!(self.inner, query_ns, name)
223 }
224
225 pub fn search_ns(&self, name: &str) -> CAresFuture<c_ares::NSResults> {
227 futurize!(self.inner, search_ns, name)
228 }
229
230 pub fn query_ptr(&self, name: &str) -> CAresFuture<c_ares::PTRResults> {
232 futurize!(self.inner, query_ptr, name)
233 }
234
235 pub fn search_ptr(&self, name: &str) -> CAresFuture<c_ares::PTRResults> {
237 futurize!(self.inner, search_ptr, name)
238 }
239
240 pub fn query_soa(&self, name: &str) -> CAresFuture<c_ares::SOAResult> {
242 futurize!(self.inner, query_soa, name)
243 }
244
245 pub fn search_soa(&self, name: &str) -> CAresFuture<c_ares::SOAResult> {
247 futurize!(self.inner, search_soa, name)
248 }
249
250 pub fn query_srv(&self, name: &str) -> CAresFuture<c_ares::SRVResults> {
252 futurize!(self.inner, query_srv, name)
253 }
254
255 pub fn search_srv(&self, name: &str) -> CAresFuture<c_ares::SRVResults> {
257 futurize!(self.inner, search_srv, name)
258 }
259
260 pub fn query_txt(&self, name: &str) -> CAresFuture<c_ares::TXTResults> {
262 futurize!(self.inner, query_txt, name)
263 }
264
265 pub fn search_txt(&self, name: &str) -> CAresFuture<c_ares::TXTResults> {
267 futurize!(self.inner, search_txt, name)
268 }
269
270 pub fn query_uri(&self, name: &str) -> CAresFuture<c_ares::URIResults> {
272 futurize!(self.inner, query_uri, name)
273 }
274
275 pub fn search_uri(&self, name: &str) -> CAresFuture<c_ares::URIResults> {
277 futurize!(self.inner, search_uri, name)
278 }
279
280 pub fn get_host_by_address(&self, address: &IpAddr) -> CAresFuture<HostResults> {
286 let (sender, receiver) = futures_channel::oneshot::channel();
287 self.inner.get_host_by_address(address, |result| {
288 let _ = sender.send(result.map(Into::into));
289 });
290 let resolver = Arc::clone(&self.inner);
291 CAresFuture::new(receiver, resolver)
292 }
293
294 pub fn get_host_by_name(
300 &self,
301 name: &str,
302 family: c_ares::AddressFamily,
303 ) -> CAresFuture<HostResults> {
304 let (sender, receiver) = futures_channel::oneshot::channel();
305 self.inner.get_host_by_name(name, family, |result| {
306 let _ = sender.send(result.map(Into::into));
307 });
308 let resolver = Arc::clone(&self.inner);
309 CAresFuture::new(receiver, resolver)
310 }
311
312 pub fn get_name_info<F>(
318 &self,
319 address: &SocketAddr,
320 flags: c_ares::NIFlags,
321 ) -> CAresFuture<NameInfoResult> {
322 let (sender, receiver) = futures_channel::oneshot::channel();
323 self.inner.get_name_info(address, flags, |result| {
324 let _ = sender.send(result.map(Into::into));
325 });
326 let resolver = Arc::clone(&self.inner);
327 CAresFuture::new(receiver, resolver)
328 }
329
330 pub fn query(&self, name: &str, dns_class: u16, query_type: u16) -> CAresFuture<Vec<u8>> {
341 let (sender, receiver) = futures_channel::oneshot::channel();
342 self.inner.query(name, dns_class, query_type, |result| {
343 let _ = sender.send(result.map(std::borrow::ToOwned::to_owned));
344 });
345 let resolver = Arc::clone(&self.inner);
346 CAresFuture::new(receiver, resolver)
347 }
348
349 pub fn search(&self, name: &str, dns_class: u16, query_type: u16) -> CAresFuture<Vec<u8>> {
360 let (sender, receiver) = futures_channel::oneshot::channel();
361 self.inner.search(name, dns_class, query_type, |result| {
362 let _ = sender.send(result.map(std::borrow::ToOwned::to_owned));
363 });
364 let resolver = Arc::clone(&self.inner);
365 CAresFuture::new(receiver, resolver)
366 }
367
368 pub fn cancel(&self) {
370 self.inner.cancel()
371 }
372}