io_tubes/tubes/
listen.rs

1use std::{io, net::SocketAddr};
2
3use tokio::{
4    io::BufReader,
5    net::{TcpListener, TcpStream, ToSocketAddrs},
6};
7
8use super::Tube;
9
10/// A TcpListener that returns Tube when a connection is accepted.
11pub struct Listener {
12    /// The inner TcpListener
13    pub inner: TcpListener,
14}
15
16impl Listener {
17    /// Create a listener by binding to the supplied address.
18    pub async fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<Self> {
19        Ok(Listener {
20            inner: TcpListener::bind(addr).await?,
21        })
22    }
23
24    /// Create a listener by binding to `0.0.0.0:0`
25    pub async fn listen() -> io::Result<Listener> {
26        Listener::bind("0.0.0.0:0").await
27    }
28
29    /// Accepts a connection.
30    pub async fn accept(&self) -> io::Result<Tube<BufReader<TcpStream>>> {
31        Ok(Tube::new(self.inner.accept().await?.0))
32    }
33
34    /// Returns the port that is listened.
35    pub fn port(&self) -> io::Result<u16> {
36        Ok(match self.inner.local_addr()? {
37            SocketAddr::V4(ip) => ip.port(),
38            SocketAddr::V6(ip) => ip.port(),
39        })
40    }
41}
42
43impl From<TcpListener> for Listener {
44    fn from(inner: TcpListener) -> Self {
45        Self { inner }
46    }
47}
48
49impl From<Listener> for TcpListener {
50    fn from(listener: Listener) -> Self {
51        listener.inner
52    }
53}