7 releases

0.3.3 Nov 1, 2021
0.3.2 Jun 10, 2021
0.3.1 Feb 18, 2021
0.2.0 Jan 1, 2021
0.1.0 Mar 17, 2020

#160 in Asynchronous

Download history 37219/week @ 2023-12-16 20408/week @ 2023-12-23 29584/week @ 2023-12-30 42744/week @ 2024-01-06 48840/week @ 2024-01-13 50729/week @ 2024-01-20 60110/week @ 2024-01-27 53899/week @ 2024-02-03 54200/week @ 2024-02-10 48878/week @ 2024-02-17 47040/week @ 2024-02-24 46021/week @ 2024-03-02 47168/week @ 2024-03-09 50316/week @ 2024-03-16 49751/week @ 2024-03-23 40400/week @ 2024-03-30

196,244 downloads per month
Used in 349 crates (8 directly)


517 lines


standard-readme compliant Build Status Docs crates.io

IntoAsyncRead on steroids

Provides a similar functionality as futures-util::IntoAsyncRead. This crate handles both AsyncRead and AsyncWrite for an underlying type that implements Stream and Sink. The stream needs to be a TryStream over I: AsRef<u8> and std::io::Error. The Sink must be over I: From< Vec<u8> > with the same error.

The main other difference is that we will always try to use the complete buffer(s) provided by clients. That is for poll_read, if more items are available on the Stream, we try to fill the entire buffer by using several messages. Implementations are provided for vectored io in order to use all buffers maximally, compared to the default implementation which would only take into account the first buffer.

For the Sink all data passed in is made into one item of the Sink.

AsyncBufRead is also implemented, which can be used to avoid a copy of the data when reading.

Care is taken when polling the underlying Stream several times, to send a dummy waker so the underlying Stream doesn't try to wake up the task when we didn't return Poll::Pending. This is, if we already have data to return, we can't return Poll::Pending. If the underlying Stream returns an error, we will buffer it for the next poll.

Table of Contents


With cargo add: cargo add async_io_stream

With cargo yaml:


   async_io_stream: ^0.3

With Cargo.toml


    async_io_stream = "0.3"


Please check out the changelog when upgrading.


This crate has few dependencies. Cargo will automatically handle it's dependencies for you.

Optionally with the map_pharos feature, the Observable trait is re-implemented and forwarded to the inner type. This allows out of band error handling, as AsyncRead/AsyncWrite can only return std::io::Error and codecs will usually stop processing the transport as soon as any error is returned. This allows notifying clients of non-fatal errors or events.

When the tokio_io feature is enabled, implementation for the traits AsyncRead/AsyncWrite from tokio are provided.


This crate uses #![ forbid(unsafe_code) ]. There is no maximum size protection for the buffers. The crate has not been fuzz tested as we never interprete any of the data that passes through.


Basic example

   async_io_stream :: { IoStream              } ,
   futures::io     :: { AsyncWrite, AsyncRead } ,
   futures         :: { Stream, Sink          } ,
   std             :: { io                    } ,

fn usage( transport: impl Stream< Item=Result<Vec<u8>, io::Error> > + Sink< Vec<u8>, Error=io::Error > + Unpin )

   -> impl AsyncRead + AsyncWrite + Unpin
	IoStream::new( transport )


API documentation can be found on docs.rs.


Please check out the contribution guidelines.


Code of conduct

Any of the behaviors described in point 4 "Unacceptable Behavior" of the Citizens Code of Conduct are not welcome here and might get you banned. If anyone including maintainers and moderators of the project fail to respect these/your limits, you are entitled to call them out.




~35K SLoC