rustrust-axum

How to create an Axum Body from an OpenDAL reader?


I need to build an Axum Body from an OpenDAL reader, but I can't find any way to achieve it. Does anybody know how to do it? Sample code:

use axum::body::Body;
use opendal::{services, Operator};
use http_body_util::StreamBody;

async fn to_body() -> Body {
    let op = Operator::new(services::Fs::default().root("./")).unwrap().finish();
    let reader = op.reader("../Cargo.toml").await.unwrap();
    let stream = reader.into_stream(..).await.unwrap();

    // stream implements futures_core::stream::Stream so I expected this to work, but it doesn't:
    // let body = Body::from_stream(stream);

    // I can build a StreamBody but then I fail to create a Body from it
    let stream_body = StreamBody::new(stream).into();

    // Now I am not able to convert the stream_body to a Body
}

Solution

  • Use .into_bytes_stream() instead:

    let stream = reader.into_bytes_stream(..).await.unwrap();
    

    Then, the resulting stream can be passed directly to Body::from_stream:

    Body::from_stream(stream)
    

    This works because Stream<Item = Result<Bytes, _>> is a semi-standardized way to represent a stream of bytes. The only potential issue could be the error conversions, but the OpenDAL stream uses std::io::Error as the error type which is already directly convertible to Box<dyn Error> that axum uses.