Skip to content

Instantly share code, notes, and snippets.

@lolgesten
Last active March 30, 2021 16:52
Show Gist options
  • Select an option

  • Save lolgesten/7f350e8c7e321c0dd2df2558173e3ad8 to your computer and use it in GitHub Desktop.

Select an option

Save lolgesten/7f350e8c7e321c0dd2df2558173e3ad8 to your computer and use it in GitHub Desktop.
futures::io::AsyncRead/AsyncWrite conversion to tokio::io::AsyncRead/AsyncWrite
use futures_io::{AsyncRead, AsyncWrite};
use std::fmt;
use std::io;
use std::pin::Pin;
use std::task::{Context, Poll};
use tokio::io::AsyncRead as TokioAsyncRead;
use tokio::io::AsyncWrite as TokioAsyncWrite;
pub trait Stream: AsyncRead + AsyncWrite + Unpin + Send + 'static {}
pub fn from_tokio<Z>(adapted: Z) -> impl Stream
where
Z: TokioAsyncRead + TokioAsyncWrite + Unpin + Send + 'static,
{
FromAdapter { adapted }
}
struct FromAdapter<Z> {
adapted: Z,
}
impl<Z: TokioAsyncRead + Unpin> AsyncRead for FromAdapter<Z> {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
Pin::new(&mut self.get_mut().adapted).poll_read(cx, buf)
}
}
impl<Z: TokioAsyncWrite + Unpin> AsyncWrite for FromAdapter<Z> {
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize, io::Error>> {
Pin::new(&mut self.get_mut().adapted).poll_write(cx, buf)
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
Pin::new(&mut self.get_mut().adapted).poll_flush(cx)
}
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
Pin::new(&mut self.get_mut().adapted).poll_shutdown(cx)
}
}
impl<Z: TokioAsyncRead + TokioAsyncWrite + Unpin + Send + 'static> Stream for FromAdapter<Z> {}
pub fn to_tokio<S: Stream>(adapted: S) -> TokioStream<S> {
TokioStream { adapted }
}
pub struct TokioStream<S> {
adapted: S,
}
impl<S: Stream> TokioAsyncRead for TokioStream<S> {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
Pin::new(&mut self.get_mut().adapted).poll_read(cx, buf)
}
}
impl<S: Stream> TokioAsyncWrite for TokioStream<S> {
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize, io::Error>> {
Pin::new(&mut self.get_mut().adapted).poll_write(cx, buf)
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
Pin::new(&mut self.get_mut().adapted).poll_flush(cx)
}
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
Pin::new(&mut self.get_mut().adapted).poll_close(cx)
}
}
@fogti
Copy link
Copy Markdown

fogti commented Mar 2, 2020

use std::fmt;

isn't needed.

@rosscanning
Copy link
Copy Markdown

Thanks heaps, mate, this really helped me out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment