Skip to main content

async_rs/util/
addr.rs

1use crate::{
2    Runtime,
3    traits::{AsyncToSocketAddrs, Executor, RuntimeKit},
4};
5use std::{
6    fmt, future, io,
7    net::{IpAddr, SocketAddr, ToSocketAddrs},
8};
9
10/// Wrapper to impl AsyncToSocketAddrs from an IntoIterator<Item = SocketAddr>
11pub struct SocketAddrs<I: IntoIterator<Item = SocketAddr> + Send + 'static>(pub I);
12
13impl<I: IntoIterator<Item = SocketAddr> + Send + 'static> AsyncToSocketAddrs for SocketAddrs<I>
14where
15    I::IntoIter: Send + 'static,
16{
17    fn to_socket_addrs(
18        self,
19    ) -> impl Future<Output = io::Result<impl Iterator<Item = SocketAddr> + Send + 'static>>
20    + Send
21    + 'static {
22        future::ready(Ok(self.0.into_iter()))
23    }
24}
25
26impl<I: IntoIterator<Item = SocketAddr> + Send + fmt::Debug + 'static> fmt::Debug
27    for SocketAddrs<I>
28{
29    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30        f.debug_tuple("SocketAddrs").field(&self.0).finish()
31    }
32}
33
34/// Iterator for SocketAddr computed from IpAddr + port
35pub struct SocketAddrsFromIpAddrs<I: Iterator<Item = IpAddr> + Send + 'static>(pub I, pub u16);
36
37impl<I: Iterator<Item = IpAddr> + Send + 'static> Iterator for SocketAddrsFromIpAddrs<I> {
38    type Item = SocketAddr;
39
40    fn next(&mut self) -> Option<Self::Item> {
41        Some(SocketAddr::new(self.0.next()?, self.1))
42    }
43}
44
45impl<I: Iterator<Item = IpAddr> + Send + 'static> fmt::Debug for SocketAddrsFromIpAddrs<I> {
46    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
47        fmt.debug_tuple("SocketAddrsFromIpAddrs").finish()
48    }
49}
50
51/// Wrapper to perform blocking name resolution on top of an async runtime
52pub struct SocketAddrsResolver<'a, RK: RuntimeKit, A: ToSocketAddrs + Send + 'static> {
53    pub(crate) runtime: &'a Runtime<RK>,
54    pub(crate) addrs: A,
55}
56
57impl<'a, RK: RuntimeKit, A: ToSocketAddrs + Send + 'static> AsyncToSocketAddrs
58    for SocketAddrsResolver<'a, RK, A>
59where
60    <A as ToSocketAddrs>::Iter: Iterator<Item = SocketAddr> + Send + 'static,
61{
62    fn to_socket_addrs(
63        self,
64    ) -> impl Future<Output = io::Result<impl Iterator<Item = SocketAddr> + Send + 'static>>
65    + Send
66    + 'static {
67        let SocketAddrsResolver { runtime, addrs } = self;
68        runtime.spawn_blocking(move || addrs.to_socket_addrs())
69    }
70}
71
72impl<'a, RK: RuntimeKit, A: ToSocketAddrs + Send + fmt::Debug + 'static> fmt::Debug
73    for SocketAddrsResolver<'a, RK, A>
74{
75    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76        f.debug_struct("SocketAddrsResolver")
77            .field("addrs", &self.addrs)
78            .finish()
79    }
80}