Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to convert an AsyncRead to a TryStream of bytes?

I have an AsyncRead and want to convert it to a Stream<Item = tokio::io::Result<Bytes>> with tokio 0.2 and futures 0.3.

The best I've been able to do is something like:

use bytes::Bytes; // 0.4.12
use futures::stream::{Stream, TryStreamExt};; // 0.3.1
use tokio::{fs::File, io::Result}; // 0.2.4
use tokio_util::{BytesCodec, FramedRead}; // 0.2.0

#[tokio::main]
async fn main() -> Result<()> {
    let file = File::open("some_file.txt").await?;
    let stream = FramedRead::new(file, BytesCodec::new()).map_ok(|b| b.freeze());
    fn_that_takes_stream(stream)
}

fn fn_that_takes_stream<S, O>(s: S) -> Result<()>
where
    S: Stream<Item = Result<Bytes>>,
{
    //...
    Ok(())
}

It seems like there should be a simpler way; I'm surprised Tokio doesn't include a codec to get a stream of Bytes instead of BytesMut or that there isn't just an extension trait that provides a method to convert an AsyncRead into a Stream. Am I missing something?

like image 873
Thayne Avatar asked Dec 13 '19 08:12

Thayne


1 Answers

If you can use tokio 1.0 or 0.3, tokio-util now has tokio_util::io::ReaderStream starting from version 0.4.

let file = File::open("some_file.txt").await?;
let stream = tokio_util::io::ReaderStream::new(file);
fn_that_takes_stream(stream)
like image 52
Martin Risell Lilja Avatar answered Oct 31 '22 10:10

Martin Risell Lilja