use alloc::{string::String, vec};
use core::{
iter,
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
option, slice,
};
use crate::executor::Executor;
pub trait ToSocketAddrs {
type Iter: Iterator<Item = SocketAddr>;
fn to_socket_addrs<EX>(&self, executor: &EX) -> impl Future<Output = crate::Result<Self::Iter>>
where
EX: Executor;
}
impl ToSocketAddrs for SocketAddr {
type Iter = option::IntoIter<SocketAddr>;
#[inline]
async fn to_socket_addrs<EX>(&self, _executor: &EX) -> crate::Result<Self::Iter>
where
EX: Executor,
{
Ok(Some(*self).into_iter())
}
}
impl ToSocketAddrs for SocketAddrV4 {
type Iter = option::IntoIter<SocketAddr>;
#[inline]
async fn to_socket_addrs<EX>(&self, executor: &EX) -> crate::Result<Self::Iter>
where
EX: Executor,
{
SocketAddr::V4(*self).to_socket_addrs(executor).await
}
}
impl ToSocketAddrs for SocketAddrV6 {
type Iter = option::IntoIter<SocketAddr>;
#[inline]
async fn to_socket_addrs<EX>(&self, executor: &EX) -> crate::Result<Self::Iter>
where
EX: Executor,
{
SocketAddr::V6(*self).to_socket_addrs(executor).await
}
}
impl ToSocketAddrs for (IpAddr, u16) {
type Iter = option::IntoIter<SocketAddr>;
#[inline]
async fn to_socket_addrs<EX>(&self, executor: &EX) -> crate::Result<Self::Iter>
where
EX: Executor,
{
let (ip, port) = *self;
match ip {
IpAddr::V4(el) => (el, port).to_socket_addrs(executor).await,
IpAddr::V6(el) => (el, port).to_socket_addrs(executor).await,
}
}
}
impl ToSocketAddrs for (Ipv4Addr, u16) {
type Iter = option::IntoIter<SocketAddr>;
#[inline]
async fn to_socket_addrs<EX>(&self, executor: &EX) -> crate::Result<Self::Iter>
where
EX: Executor,
{
let (ip, port) = *self;
SocketAddrV4::new(ip, port).to_socket_addrs(executor).await
}
}
impl ToSocketAddrs for (Ipv6Addr, u16) {
type Iter = option::IntoIter<SocketAddr>;
#[inline]
async fn to_socket_addrs<EX>(&self, executor: &EX) -> crate::Result<Self::Iter>
where
EX: Executor,
{
let (ip, port) = *self;
SocketAddrV6::new(ip, port, 0, 0).to_socket_addrs(executor).await
}
}
impl ToSocketAddrs for (&str, u16) {
type Iter = vec::IntoIter<SocketAddr>;
#[inline]
async fn to_socket_addrs<EX>(&self, _executor: &EX) -> crate::Result<Self::Iter>
where
EX: Executor,
{
cfg_select! {
feature = "tokio" => {
if EX::TY.is_std() {
Ok(<Self as std::net::ToSocketAddrs>::to_socket_addrs(self)?)
} else {
Ok(vec::Vec::from_iter(tokio::net::lookup_host(self).await?).into_iter())
}
},
feature = "std" => Ok(<Self as std::net::ToSocketAddrs>::to_socket_addrs(self)?),
_ => Err(crate::net::NetError::NoResolutionBackend.into()),
}
}
}
impl ToSocketAddrs for (String, u16) {
type Iter = vec::IntoIter<SocketAddr>;
#[inline]
async fn to_socket_addrs<EX>(&self, executor: &EX) -> crate::Result<Self::Iter>
where
EX: Executor,
{
(&*self.0, self.1).to_socket_addrs(executor).await
}
}
impl ToSocketAddrs for str {
type Iter = vec::IntoIter<SocketAddr>;
#[inline]
async fn to_socket_addrs<EX>(&self, _executor: &EX) -> crate::Result<Self::Iter>
where
EX: Executor,
{
cfg_select! {
feature = "tokio" => {
if EX::TY.is_std() {
Ok(<Self as std::net::ToSocketAddrs>::to_socket_addrs(self)?)
} else {
Ok(vec::Vec::from_iter(tokio::net::lookup_host(self).await?).into_iter())
}
}
feature = "std" => Ok(<Self as std::net::ToSocketAddrs>::to_socket_addrs(self)?),
_ => Err(crate::net::NetError::NoResolutionBackend.into()),
}
}
}
impl<'any> ToSocketAddrs for &'any [SocketAddr] {
type Iter = iter::Copied<slice::Iter<'any, SocketAddr>>;
#[inline]
async fn to_socket_addrs<EX>(&self, _executor: &EX) -> crate::Result<Self::Iter>
where
EX: Executor,
{
Ok(self.iter().copied())
}
}
impl<T: ToSocketAddrs + ?Sized> ToSocketAddrs for &T {
type Iter = T::Iter;
#[inline]
async fn to_socket_addrs<EX>(&self, executor: &EX) -> crate::Result<T::Iter>
where
EX: Executor,
{
(**self).to_socket_addrs(executor).await
}
}
impl ToSocketAddrs for String {
type Iter = vec::IntoIter<SocketAddr>;
#[inline]
async fn to_socket_addrs<EX>(&self, executor: &EX) -> crate::Result<Self::Iter>
where
EX: Executor,
{
(**self).to_socket_addrs(executor).await
}
}