1use std::net::SocketAddr;
4use std::sync::{Arc, OnceLock};
5
6use ouroboros::self_referencing;
7use reqwest::dns::{Addrs, Name, Resolve, Resolving};
8
9use crate::IpAddrIterator;
10use crate::protocol::interpret_data;
11use crate::tokio::fill_buf;
12
13pub fn resolver() -> Arc<Resolver> {
15 static RESOLVER: OnceLock<Arc<Resolver>> = OnceLock::new();
16
17 Arc::clone(RESOLVER.get_or_init(|| Arc::new(Resolver)))
18}
19
20#[derive(Debug, Clone, Copy, Default)]
22pub struct Resolver;
23
24impl Resolve for Resolver {
25 #[inline]
26 fn resolve(&self, name: Name) -> Resolving {
27 Box::pin(resolve(name))
28 }
29}
30
31async fn resolve(name: Name) -> Result<Addrs, Box<dyn std::error::Error + Send + Sync>> {
32 let mut buf = Vec::new();
33 if let Some(resp) = fill_buf(name.as_str().as_bytes(), &mut buf).await? {
34 let addrs = ResolvedAddrs::try_new(buf, |buf| interpret_data(&resp, buf))?;
35 Ok(Box::new(addrs))
36 } else {
37 Err(Box::new(NoResults(name)))
38 }
39}
40
41#[self_referencing]
42struct ResolvedAddrs {
43 buf: Vec<u8>,
44 #[borrows(buf)]
45 #[covariant]
46 iter: IpAddrIterator<'this>,
47}
48
49impl Iterator for ResolvedAddrs {
50 type Item = SocketAddr;
51
52 fn next(&mut self) -> Option<Self::Item> {
53 self.with_iter_mut(|iter| Some(SocketAddr::new(iter.next()?, 0)))
54 }
55}
56
57#[derive(Debug, thiserror::Error, displaydoc::Display)]
59struct NoResults(Name);