Hi,
And kudos for this very promising project.
I'm currently trying to replace all instances of futures.rs and tokio with async-std.
However, hyper requires streams that implement the tokio::io::AsyncRead and AsyncWrite traits.
Given a stream obtained from async-std, such as a TcpStream, how can I get something that implements tokio's traits?
Thanks again for async-std!
I'll take a look at it tomorrow, but on cursory glance, it's probably best to implement tokio::io::AsyncRead/Write outside of this lib as implementing them inside of it is not in scope. We lobby for using futures-rs as the generic way of compatibility between libraries.
FWIW, here's the trick to implement a foreign trait for a foreign type:
use async_std::net::TcpStream;
use some::foreign::Trait;
struct CompatStream(TcpStream);
impl Trait for CompatStream {
//... use `compat_stream.0` here
}
Probably not the best way to do it, but that did the trick:
use async_std::net::TcpStream;
use async_std::os::unix::net::UnixStream;
use async_std::task::{Context, Poll};
use futures::io::{AsyncRead, AsyncWrite};
use std::io;
use std::pin::Pin;
pub struct TokioCompat<T>(T);
pub trait TokioCompatExt: AsyncRead + AsyncWrite + Sized {
#[inline]
fn compat(self) -> TokioCompat<Self> {
TokioCompat(self)
}
}
impl<T: AsyncRead + Unpin> tokio::io::AsyncRead for TokioCompat<T> {
#[inline]
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context,
buf: &mut [u8],
) -> Poll<Result<usize, io::Error>> {
Pin::new(&mut self.0).poll_read(cx, buf)
}
}
impl<T: AsyncWrite + Unpin> tokio::io::AsyncWrite for TokioCompat<T> {
#[inline]
fn poll_write(
mut self: Pin<&mut Self>,
cx: &mut Context,
buf: &[u8],
) -> Poll<Result<usize, io::Error>> {
Pin::new(&mut self.0).poll_write(cx, buf)
}
#[inline]
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), io::Error>> {
Pin::new(&mut self.0).poll_flush(cx)
}
#[inline]
fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), io::Error>> {
Pin::new(&mut self.0).poll_close(cx)
}
}
impl TokioCompatExt for UnixStream {}
impl TokioCompatExt for TcpStream {}
hyper still uses tokio's primitives so I'm not sure about getting rid of tokio, at least you'll need it's reactor
hyper still uses tokio's primitives so I'm not sure about getting rid of tokio, at least you'll need it's reactor
And probably the whole tokio runtime as I'm sure hyper also makes use of its timer infrastructure for example.
However,
hyperrequires streams that implement thetokio::io::AsyncReadandAsyncWritetraits.
I believe the correct way forward here would be for tokio (or more specifically tokio-io) to simply re-export the traits from the futures crate instead of defining their own. I don't think there's a reason left for a separate trait definition. But obviously that would have to be taken up with the tokio project :)
And probably the whole tokio runtime as I'm sure hyper also makes use of its timer infrastructure for example.
No, you only need reactor as it is used to interact with mio.
You can disable runtime features
As async-std has own reactor, it makes them incompatible.
I am learning rust and I would like to know what would be the best way to perform async http requests using async-std if you are not coupled to Hyper/Tokio?
Maybe using reqwest in an async function?
I can recommend using https://github.com/rustasync/surf
How about HTTP server? Is there any implementation that uses async-std (may be even in pipeline currently)?
@opensourcegeek Try Tide
I'm trying to build a proxy, that accepts and connects to Unix sockets and fixed IP addresses, so the surf +tide combo doesn't seem to be an option. Back to tokio :(
It seems conversation has settled down here so I'm going to go ahead and close this. Thanks everyone!
Most helpful comment
I can recommend using https://github.com/rustasync/surf