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