#[cfg(feature = "tokio")] mod tokio_tests { use std::str::FromStr; use protwrap::tokio::{ client::connector, server::listener::{ async_trait, Acceptor, KillSwitch, Listener, SockAddr }, ServerStream }; use tokio::{ io::{AsyncReadExt, AsyncWriteExt}, sync::oneshot }; struct MyAcceptor { tx_port: Option>, ks: KillSwitch, did_bind: bool, did_connect: bool, did_unbind: bool } #[async_trait] impl Acceptor for MyAcceptor { async fn bound(&mut self, _listener: &Listener, sa: SockAddr) { self.did_bind = true; let port = sa.unwrap_std().port(); let Some(tx) = self.tx_port.take() else { panic!("Channel end-point missing"); }; tx.send(port).unwrap(); } async fn unbound(&mut self, _listener: &Listener) { self.did_unbind = true; } async fn connected(&mut self, _sa: SockAddr, mut strm: ServerStream) { self.did_connect = true; let killswitch = self.ks.clone(); tokio::task::spawn(async move { let mut buf = [0u8; 5]; let n = strm.read(&mut buf[..]).await.unwrap(); assert_eq!(n, 5); assert_eq!(buf, *b"hello"); let n = strm.write(b"world").await.unwrap(); assert_eq!(n, 5); killswitch.trigger(); }); } } #[tokio::test] async fn main() { let (tx, rx) = oneshot::channel(); let listener = Listener::from_str("127.0.0.1:0").unwrap(); let ks = KillSwitch::new(); let acceptor = MyAcceptor { tx_port: Some(tx), ks: ks.clone(), did_bind: false, did_connect: false, did_unbind: false }; let killswitch = ks.clone(); let jh_server = tokio::task::spawn(async move { listener.run(killswitch, acceptor).await.unwrap(); }); let jh_client = tokio::task::spawn(async move { // Use side-channel to receive port number from server let port = rx.await.unwrap(); let addr = format!("127.0.0.1:{port}"); let c = connector::Connector::from_str(&addr).unwrap(); let mut strm = c.connect().await.unwrap(); println!("server: Sending 'hello' to client"); let n = strm.write(b"hello").await.unwrap(); assert_eq!(n, 5); let mut buf = [0u8; 5]; let n = strm.read(&mut buf[..]).await.unwrap(); assert_eq!(n, 5); assert_eq!(buf, *b"world"); }); ks.wait().await; jh_client.await.unwrap(); jh_server.await.unwrap(); } } // vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 :