use smallvec::SmallVec;
use std::io;
use std::net::SocketAddr;
#[cfg(feature = "async")]
use crate::future::BoxFuture;
pub trait ToSocketAddrs {
type Iter: IntoIterator<Item = SocketAddr>;
#[cfg(feature = "async")]
fn to_socket_addrs(&self) -> BoxFuture<io::Result<Self::Iter>>;
#[cfg(feature = "blocking")]
fn to_socket_addrs_blocking(&self) -> io::Result<Self::Iter>;
}
impl<A: ToSocketAddrs + ?Sized> ToSocketAddrs for &'_ A {
type Iter = A::Iter;
#[cfg(feature = "async")]
fn to_socket_addrs(&self) -> BoxFuture<io::Result<Self::Iter>> {
(*self).to_socket_addrs()
}
#[cfg(feature = "blocking")]
fn to_socket_addrs_blocking(&self) -> io::Result<Self::Iter> {
(*self).to_socket_addrs_blocking()
}
}
impl ToSocketAddrs for str {
type Iter = smallvec::IntoIter<[SocketAddr; 2]>;
#[cfg(feature = "async")]
fn to_socket_addrs(&self) -> BoxFuture<io::Result<Self::Iter>> {
Box::pin(async move {
let addresses: SmallVec<[SocketAddr; 2]> = pick_async_runtime_async!(self, {
"async-std" => |host| async move {
let addresses = <Self as async_std::net::ToSocketAddrs>::to_socket_addrs(host).await?;
let addresses = SmallVec::<[SocketAddr; 2]>::from_iter(addresses);
Ok::<_, io::Error>(addresses)
},
"tokio" => |host| async move {
let addresses = tokio::net::lookup_host(host).await?;
let addresses = SmallVec::<[SocketAddr; 2]>::from_iter(addresses);
Ok::<_, io::Error>(addresses)
},
})
.resolve().await
.into_result()
.map_err(|err: io::Error| err)?
.into_inner();
Ok(addresses.into_iter())
})
}
#[cfg(feature = "blocking")]
fn to_socket_addrs_blocking(&self) -> io::Result<Self::Iter> {
let addresses = std::net::ToSocketAddrs::to_socket_addrs(self)?;
let addresses = SmallVec::<[SocketAddr; 2]>::from_iter(addresses);
Ok(addresses.into_iter())
}
}