nautalid 0.1.0

Scratch container substrate — TLS 1.3 HTTP/2+3 kernel, LID/AetherDB, optional filter bus (GPL-3.0-or-later).
//! [`reqwest::dns::Resolve`] adapter over Hickory.

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)
        })
    }
}