]> git.lizzy.rs Git - connect-rs.git/blob - src/tcp/server.rs
avoid block_on as much as possible
[connect-rs.git] / src / tcp / server.rs
1 use crate::Connection;
2 use async_std::net::{SocketAddr, TcpListener, ToSocketAddrs};
3 use async_std::pin::Pin;
4 use futures::task::{Context, Poll};
5 use futures::Stream;
6 use futures_lite::stream::StreamExt;
7 use log::*;
8
9 #[allow(dead_code)]
10 pub struct TcpServer {
11     local_addrs: SocketAddr,
12     listener: TcpListener,
13 }
14
15 impl TcpServer {
16     pub async fn new<A: ToSocketAddrs + std::fmt::Display>(ip_addrs: A) -> anyhow::Result<Self> {
17         let listener = TcpListener::bind(&ip_addrs).await?;
18         info!("Started TCP server at {}", &ip_addrs);
19
20         Ok(Self {
21             local_addrs: listener.local_addr()?,
22             listener,
23         })
24     }
25 }
26
27 impl Stream for TcpServer {
28     type Item = Connection;
29
30     fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
31         match self.listener.incoming().poll_next(cx) {
32             Poll::Pending => Poll::Pending,
33
34             Poll::Ready(Some(Ok(conn))) => {
35                 debug!(
36                     "Received connection attempt from {}",
37                     conn.peer_addr()
38                         .expect("Peer address could not be retrieved")
39                 );
40
41                 Poll::Ready(Some(Connection::from(conn)))
42             },
43
44             Poll::Ready(Some(Err(e))) => {
45                 error!(
46                     "Encountered error when accepting connection attempt: {}", e
47                 );
48
49                 Poll::Pending
50             },
51
52             Poll::Ready(None) => {
53                 info!("Shutting TCP server down at {}", self.local_addrs);
54                 Poll::Ready(None)
55             },
56         }
57     }
58 }