use std::pin::Pin;
use std::task::{Context, Poll};
use iroh::endpoint::{RecvStream, SendStream};
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
pub struct IrohDuplex {
send: SendStream,
recv: RecvStream,
}
impl IrohDuplex {
pub fn new(send: SendStream, recv: RecvStream) -> Self {
Self { send, recv }
}
}
impl AsyncRead for IrohDuplex {
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut ReadBuf<'_>,
) -> Poll<std::io::Result<()>> {
Pin::new(&mut self.recv).poll_read(cx, buf)
}
}
impl AsyncWrite for IrohDuplex {
fn poll_write(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<std::io::Result<usize>> {
match Pin::new(&mut self.send).poll_write(cx, buf) {
Poll::Ready(Ok(written)) => Poll::Ready(Ok(written)),
Poll::Ready(Err(err)) => Poll::Ready(Err(std::io::Error::other(err))),
Poll::Pending => Poll::Pending,
}
}
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
match Pin::new(&mut self.send).poll_flush(cx) {
Poll::Ready(Ok(())) => Poll::Ready(Ok(())),
Poll::Ready(Err(err)) => Poll::Ready(Err(std::io::Error::other(err))),
Poll::Pending => Poll::Pending,
}
}
fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
match Pin::new(&mut self.send).poll_shutdown(cx) {
Poll::Ready(Ok(())) => Poll::Ready(Ok(())),
Poll::Ready(Err(err)) => Poll::Ready(Err(std::io::Error::other(err))),
Poll::Pending => Poll::Pending,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_irohduplex_send_sync() {
fn assert_send_sync<T: Send + Sync>() {}
assert_send_sync::<IrohDuplex>();
}
}