1use async_trait::async_trait;
7use std::io;
8use tokio::io::{AsyncRead, AsyncWrite};
9
10#[async_trait(?Send)]
15pub trait NetworkProvider: Clone {
16 type TcpStream: AsyncRead + AsyncWrite + Unpin + 'static;
18 type TcpListener: TcpListenerTrait<TcpStream = Self::TcpStream> + 'static;
20
21 async fn bind(&self, addr: &str) -> io::Result<Self::TcpListener>;
23
24 async fn connect(&self, addr: &str) -> io::Result<Self::TcpStream>;
26}
27
28#[async_trait(?Send)]
30pub trait TcpListenerTrait {
31 type TcpStream: AsyncRead + AsyncWrite + Unpin + 'static;
33
34 async fn accept(&self) -> io::Result<(Self::TcpStream, String)>;
36
37 fn local_addr(&self) -> io::Result<String>;
39}
40
41#[derive(Debug, Clone)]
43pub struct TokioNetworkProvider;
44
45impl TokioNetworkProvider {
46 pub fn new() -> Self {
48 Self
49 }
50}
51
52impl Default for TokioNetworkProvider {
53 fn default() -> Self {
54 Self::new()
55 }
56}
57
58#[async_trait(?Send)]
59impl NetworkProvider for TokioNetworkProvider {
60 type TcpStream = tokio::net::TcpStream;
61 type TcpListener = TokioTcpListener;
62
63 async fn bind(&self, addr: &str) -> io::Result<Self::TcpListener> {
64 let listener = tokio::net::TcpListener::bind(addr).await?;
65 Ok(TokioTcpListener { inner: listener })
66 }
67
68 async fn connect(&self, addr: &str) -> io::Result<Self::TcpStream> {
69 tokio::net::TcpStream::connect(addr).await
70 }
71}
72
73#[derive(Debug)]
75pub struct TokioTcpListener {
76 inner: tokio::net::TcpListener,
77}
78
79#[async_trait(?Send)]
80impl TcpListenerTrait for TokioTcpListener {
81 type TcpStream = tokio::net::TcpStream;
82
83 async fn accept(&self) -> io::Result<(Self::TcpStream, String)> {
84 let (stream, addr) = self.inner.accept().await?;
85 Ok((stream, addr.to_string()))
86 }
87
88 fn local_addr(&self) -> io::Result<String> {
89 Ok(self.inner.local_addr()?.to_string())
90 }
91}