init
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
use color_eyre::Result;
|
||||
use tokio::io::{AsyncRead, AsyncWrite, copy_bidirectional};
|
||||
|
||||
/// Bidirectional relay between two async streams.
|
||||
/// Returns when either direction hits EOF or an error.
|
||||
pub async fn relay<A, B>(mut a: A, mut b: B) -> Result<()>
|
||||
where
|
||||
A: AsyncRead + AsyncWrite + Unpin,
|
||||
B: AsyncRead + AsyncWrite + Unpin,
|
||||
{
|
||||
copy_bidirectional(&mut a, &mut b).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Wrapper to combine a QUIC send+recv into a single AsyncRead+AsyncWrite.
|
||||
pub struct QuicBiStream {
|
||||
pub send: quinn::SendStream,
|
||||
pub recv: quinn::RecvStream,
|
||||
}
|
||||
|
||||
impl tokio::io::AsyncRead for QuicBiStream {
|
||||
fn poll_read(
|
||||
mut self: std::pin::Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
buf: &mut tokio::io::ReadBuf<'_>,
|
||||
) -> std::task::Poll<std::io::Result<()>> {
|
||||
std::pin::Pin::new(&mut self.recv).poll_read(cx, buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl tokio::io::AsyncWrite for QuicBiStream {
|
||||
fn poll_write(
|
||||
mut self: std::pin::Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
buf: &[u8],
|
||||
) -> std::task::Poll<std::io::Result<usize>> {
|
||||
std::pin::Pin::new(&mut self.send)
|
||||
.poll_write(cx, buf)
|
||||
.map(|r| r.map_err(std::io::Error::other))
|
||||
}
|
||||
|
||||
fn poll_flush(
|
||||
mut self: std::pin::Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
) -> std::task::Poll<std::io::Result<()>> {
|
||||
std::pin::Pin::new(&mut self.send).poll_flush(cx)
|
||||
}
|
||||
|
||||
fn poll_shutdown(
|
||||
mut self: std::pin::Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
) -> std::task::Poll<std::io::Result<()>> {
|
||||
std::pin::Pin::new(&mut self.send).poll_shutdown(cx)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user