use std::net::{SocketAddr, ToSocketAddrs};
#[derive(thiserror::Error, Debug)]
pub enum DomainResolveError {
#[error("Io error: {}", .0)]
IoError(#[from] std::io::Error),
#[error("Failed to resolve domain.")]
#[allow(unused)]
NoIpsFound,
}
#[allow(unused)]
pub async fn resolve_to_ips(
domain: &str,
port: u16,
) -> Result<Box<[SocketAddr]>, DomainResolveError> {
let addrs = (domain, port).to_socket_addrs()?;
let (ipv4s, ipv6s) = addrs.into_iter().partition::<Vec<_>, _>(|ip| ip.is_ipv4());
let ips_count = ipv4s.len() + ipv6s.len();
if ips_count == 0 {
return Err(DomainResolveError::NoIpsFound);
}
let mut left = ipv6s.into_iter();
let mut right = ipv4s.into_iter();
let mut interlaced = Vec::with_capacity(ips_count);
for (l, r) in (&mut left).zip(&mut right) {
interlaced.push(l);
interlaced.push(r);
}
interlaced.extend(left);
interlaced.extend(right);
Ok(interlaced.into_boxed_slice())
}