async_stream_connection/
listener.rs

1use tokio::net::TcpListener;
2#[cfg(unix)]
3use tokio::net::UnixListener;
4
5use std::io;
6#[cfg(unix)]
7use std::os::unix::io::{AsRawFd, RawFd};
8
9use crate::{Addr, Stream};
10
11/// A socket server, listening for connections.
12///
13/// You can accept a new connection by using the [`Listener::accept`] method.
14pub enum Listener {
15    /// A TCP socket server, listening for connections.
16    Inet(TcpListener),
17    #[cfg(unix)]
18    /// A Unix socket which can accept connections from other Unix sockets.
19    Unix(UnixListener),
20}
21impl Listener {
22    /// Creates a new Listener, which will be bound to the specified address.
23    ///
24    /// The returned listener is ready for accepting connections.
25    pub async fn bind(s: &Addr) -> io::Result<Listener> {
26        match s {
27            Addr::Inet(s) => TcpListener::bind(s).await.map(Listener::Inet),
28            #[cfg(unix)]
29            Addr::Unix(s) => UnixListener::bind(s).map(Listener::Unix),
30        }
31    }
32    /// Accepts a new incoming connection from this listener.
33    /// 
34    /// This function will yield once a new connection is established.
35    /// When established, the corresponding [`Stream`] and the remote peer’s address will be returned.
36    pub async fn accept(&self) -> io::Result<(Stream, Addr)> {
37        match self {
38            Listener::Inet(s) => s
39                .accept()
40                .await
41                .map(|(s, a)| (Stream::Inet(s), Addr::Inet(a))),
42            #[cfg(unix)]
43            Listener::Unix(s) => s
44                .accept()
45                .await
46                .map(|(s, a)| (Stream::Unix(s), Addr::from(a))),
47        }
48    }
49}
50#[cfg(unix)]
51impl AsRawFd for Listener {
52    fn as_raw_fd(&self) -> RawFd {
53        match self {
54            Listener::Inet(s) => s.as_raw_fd(),
55            #[cfg(unix)]
56            Listener::Unix(s) => s.as_raw_fd(),
57        }
58    }
59}
60#[cfg(unix)]
61impl Drop for Listener {
62    fn drop(&mut self) {
63        if let Listener::Unix(l) = self {
64            if let Ok(a) = l.local_addr() {
65                if let Some(path) = a.as_pathname() {
66                    std::fs::remove_file(path).unwrap();
67                }
68            }
69        }
70    }
71}