fut_compat/net/
mod.rs

1use std::net::{
2    SocketAddr,
3    SocketAddrV4,
4    SocketAddrV6,
5    IpAddr,
6};
7use std::str::FromStr;
8use std::path::Path;
9
10use async_trait::async_trait;
11
12
13
14/// Contains the compatibility objects for the [`tokio`](https://docs.rs/tokio) runtime.
15#[cfg(feature = "tokio-rt")]
16#[cfg_attr(docsrs, doc(cfg(feature = "tokio-rt")))]
17mod tokio;
18#[cfg(feature = "tokio-rt")]
19#[cfg_attr(docsrs, doc(cfg(feature = "tokio-rt")))]
20pub use self::tokio::*;
21
22/// Contains the compatibility objects for the [`async_std`](https://docs.rs/async-std) runtime.
23#[cfg(feature = "async-std-rt")]
24#[cfg_attr(docsrs, doc(cfg(feature = "async-std-rt")))]
25mod async_std;
26#[cfg(feature = "async-std-rt")]
27#[cfg_attr(docsrs, doc(cfg(feature = "async-std-rt")))]
28pub use self::async_std::*;
29
30
31
32/// An async abstraction over [`std::os::unix::net::SocketAddr`].
33#[cfg(unix)]
34#[cfg_attr(docsrs, doc(cfg(unix)))]
35pub trait UnixSocketAddr {
36    /// Returns `true` if the address is unnamed.
37    fn is_unnamed(&self) -> bool;
38
39    /// Returns the contents of this address if it is a `pathname` address.
40    fn as_pathname(&self) -> Option<&Path>;
41}
42
43#[cfg(unix)]
44#[cfg_attr(docsrs, doc(cfg(unix)))]
45impl UnixSocketAddr for std::os::unix::net::SocketAddr {
46    fn is_unnamed(&self) -> bool {
47        self.is_unnamed()
48    }
49
50    fn as_pathname(&self) -> Option<&Path> {
51        self.as_pathname()
52    }
53}
54
55
56
57/// An async abstraction over [`std::net::ToSocketAddrs`].
58///
59/// Converts or resolves addresses to [`SocketAddr`] values.
60#[async_trait]
61pub trait ToSocketAddrs {
62    type Iter: Iterator<Item = SocketAddr>;
63
64    async fn to_socket_addrs(self) -> Self::Iter;
65}
66
67#[async_trait]
68impl<I> ToSocketAddrs for (I, u16)
69where
70    I: Into<IpAddr> + Send,
71{
72    type Iter = std::array::IntoIter<SocketAddr, 1>;
73
74    async fn to_socket_addrs(self) -> Self::Iter {
75        let addr: SocketAddr = self.into();
76
77        IntoIterator::into_iter([addr])
78    }
79}
80
81#[async_trait]
82impl ToSocketAddrs for SocketAddrV4 {
83    type Iter = std::array::IntoIter<SocketAddr, 1>;
84
85    async fn to_socket_addrs(self) -> Self::Iter {
86        let addr: SocketAddr = self.into();
87
88        IntoIterator::into_iter([addr])
89    }
90}
91
92#[async_trait]
93impl ToSocketAddrs for SocketAddrV6 {
94    type Iter = std::array::IntoIter<SocketAddr, 1>;
95
96    async fn to_socket_addrs(self) -> Self::Iter {
97        let addr: SocketAddr = self.into();
98
99        IntoIterator::into_iter([addr])
100    }
101}
102
103#[async_trait]
104impl ToSocketAddrs for String {
105    type Iter = std::vec::IntoIter<SocketAddr>;
106
107    async fn to_socket_addrs(self) -> Self::Iter {
108        let addr: Vec<SocketAddr> = match SocketAddr::from_str(&self) {
109            Ok(addr) => vec![addr],
110            Err(_) => Vec::new(),
111        };
112
113        IntoIterator::into_iter(addr)
114    }
115}
116
117#[async_trait]
118impl ToSocketAddrs for &str {
119    type Iter = std::vec::IntoIter<SocketAddr>;
120
121    async fn to_socket_addrs(self) -> Self::Iter {
122        let addr: Vec<SocketAddr> = match SocketAddr::from_str(self) {
123            Ok(addr) => vec![addr],
124            Err(_) => Vec::new(),
125        };
126
127        IntoIterator::into_iter(addr)
128    }
129}
130
131#[async_trait]
132impl ToSocketAddrs for &[SocketAddr] {
133    type Iter = std::vec::IntoIter<SocketAddr>;
134
135    async fn to_socket_addrs(self) -> Self::Iter {
136        let addr: Vec<SocketAddr> = self.iter().map(|&addr| addr).collect();
137
138        IntoIterator::into_iter(addr)
139    }
140}
141
142
143
144/// An async abstraction over [`std::net::TcpStream`].
145#[async_trait]
146pub trait TcpStream: Sized {
147    /// Opens a TCP connection to a remote host.
148    ///
149    /// `addrs` is an address of the remote host. Anything which implements the
150    /// [`ToSocketAddrs`] trait can be supplied as the address.  If `addrs`
151    /// yields multiple addresses, connect will be attempted with each of the
152    /// addresses until a connection is successful. If none of the addresses
153    /// result in a successful connection, the error returned from the last
154    /// connection attempt (the last address) is returned.
155    async fn connect<A: ToSocketAddrs + Send>(addrs: A) -> std::io::Result<Self>;
156
157    /// Receives data on the socket from the remote address to which it is connected, without
158    /// removing that data from the queue.
159    ///
160    /// On success, returns the number of bytes peeked.
161    ///
162    /// Successive calls return the same data. This is accomplished by passing `MSG_PEEK` as a flag
163    /// to the underlying `recv` system call.
164    async fn peek(&self, buf: &mut [u8]) -> std::io::Result<usize>;
165
166    /// Returns the remote address that this stream is connected to.
167    fn peer_addr(&self) -> std::io::Result<SocketAddr>;
168
169    /// Returns the local address that this stream is connected to.
170    fn local_addr(&self) -> std::io::Result<SocketAddr>;
171
172    /// Gets the value of the `TCP_NODELAY` option on this socket.
173    ///
174    /// For more information about this option, see [`set_nodelay`].
175    ///
176    /// [`set_nodelay`]: #tymethod.set_nodelay
177    fn nodelay(&self) -> std::io::Result<bool>;
178
179    /// Sets the value of the `TCP_NODELAY` option on this socket.
180    ///
181    /// If set, this option disables the Nagle algorithm. This means that
182    /// segments are always sent as soon as possible, even if there is only a
183    /// small amount of data. When not set, data is buffered until there is a
184    /// sufficient amount to send out, thereby avoiding the frequent sending of
185    /// small packets.
186    fn set_nodelay(&self, nodelay: bool) -> std::io::Result<()>;
187
188    /// Gets the value of the `IP_TTL` option for this socket.
189    ///
190    /// For more information about this option, see [`set_ttl`].
191    ///
192    /// [`set_ttl`]: #tymethod.set_ttl
193    fn ttl(&self) -> std::io::Result<u32>;
194
195    /// Sets the value for the `IP_TTL` option on this socket.
196    ///
197    /// This value sets the time-to-live field that is used in every packet sent
198    /// from this socket.
199    fn set_ttl(&self, ttl: u32) -> std::io::Result<()>;
200}
201
202
203
204/// An async abstraction over [`std::net::TcpListener`].
205#[async_trait]
206pub trait TcpListener: Sized {
207    type TcpStream: TcpStream;
208
209    /// Creates a new `TcpListener` which will be bound to the specified address.
210    ///
211    /// The returned listener is ready for accepting connections.
212    ///
213    /// Binding with a port number of 0 will request that the OS assigns a port to this listener.
214    /// The port allocated can be queried via the [`local_addr`] method.
215    ///
216    /// [`local_addr`]: #tymethod.local_addr
217    async fn bind<A: ToSocketAddrs + Send>(addrs: A) -> std::io::Result<Self>;
218
219    /// Accepts a new incoming connection to this listener.
220    ///
221    /// When a connection is established, the corresponding stream and address will be returned.
222    async fn accept(&self) -> std::io::Result<(Self::TcpStream, SocketAddr)>;
223
224    /// Returns the local address that this listener is bound to.
225    ///
226    /// This can be useful, for example, to identify when binding to port 0 which port was assigned
227    /// by the OS.
228    fn local_addr(&self) -> std::io::Result<SocketAddr>;
229}
230
231
232
233
234/// An async abstraction over [`std::os::unix::net::UnixStream`].
235#[cfg(unix)]
236#[cfg_attr(docsrs, doc(cfg(unix)))]
237#[async_trait]
238pub trait UnixStream: Sized {
239    type SocketAddr: UnixSocketAddr;
240
241    /// Connects to the socket to the specified address.
242    async fn connect<P: AsRef<Path> + Send>(path: P) -> std::io::Result<Self>;
243
244    /// Creates an unnamed pair of connected sockets.
245    ///
246    /// Returns two streams which are connected to each other.
247    fn pair() -> std::io::Result<(Self, Self)>;
248
249    /// Returns the socket address of the local half of this connection.
250    fn peer_addr(&self) -> std::io::Result<Self::SocketAddr>;
251
252    /// Returns the socket address of the remote half of this connection.
253    fn local_addr(&self) -> std::io::Result<Self::SocketAddr>;
254}
255
256
257
258/// An async abstraction over [`std::os::unix::net::UnixListener`].
259#[cfg(unix)]
260#[cfg_attr(docsrs, doc(cfg(unix)))]
261#[async_trait]
262pub trait UnixListener: Sized {
263    type UnixStream: UnixStream;
264    type SocketAddr: UnixSocketAddr;
265
266    /// Creates a new unix listener bound to the specified path.
267    async fn bind<P: AsRef<Path> + Send>(path: P) -> std::io::Result<Self>;
268
269    /// Accepts a new incoming connection to this listener.
270    ///
271    /// When a connection is established, the corresponding stream and address will be returned.
272    async fn accept(&self) -> std::io::Result<(Self::UnixStream, Self::SocketAddr)>;
273
274    /// Returns the local socket address of this listener.
275    fn local_addr(&self) -> std::io::Result<Self::SocketAddr>;
276}