use std::net::SocketAddr;
use std::sync::Arc;
use std::net::IpAddr;
use hickory_resolver::TokioResolver;
use reqwest::dns::{Addrs, Name, Resolve, Resolving};
#[derive(Clone)]
pub struct HickoryReqwestResolver {
inner: Arc<TokioResolver>,
}
impl HickoryReqwestResolver {
pub fn new(inner: Arc<TokioResolver>) -> Self {
Self { inner }
}
}
struct SocketAddrs {
iter: std::vec::IntoIter<IpAddr>,
}
impl Iterator for SocketAddrs {
type Item = SocketAddr;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|ip| SocketAddr::new(ip, 0))
}
}
impl Resolve for HickoryReqwestResolver {
fn resolve(&self, name: Name) -> Resolving {
let resolver = Arc::clone(&self.inner);
Box::pin(async move {
let lookup = resolver
.lookup_ip(name.as_str())
.await
.map_err(|e| -> Box<dyn std::error::Error + Send + Sync> { Box::new(e) })?;
let addrs: Addrs = Box::new(SocketAddrs {
iter: lookup.iter().collect::<Vec<_>>().into_iter(),
});
Ok(addrs)
})
}
}