Module compat

Module compat 

Source
Available on crate feature compat only.
Expand description

Compatibility between the tokio::io and futures-io versions of the AsyncRead and AsyncWrite traits.

§Bridging Tokio and Futures I/O with compat()

The compat() function provides a compatibility layer that allows types implementing tokio::io::AsyncRead or tokio::io::AsyncWrite to be used as their futures::io::AsyncRead or futures::io::AsyncWrite counterparts — and vice versa.

This is especially useful when working with libraries that expect I/O types from one ecosystem (usually futures) but you are using types from the other (usually tokio).

§Compatibility Overview

§Feature Flag

This functionality is available through the compat feature flag:

tokio-util = { version = "...", features = ["compat"] }

§Example 1: Tokio -> Futures (AsyncRead)

This example demonstrates sending data over a tokio::net::TcpStream and using futures::io::AsyncReadExt::read from the futures crate to read it after adapting the stream via compat().

use tokio::net::{TcpListener, TcpStream};
use tokio::io::AsyncWriteExt;
use tokio_util::compat::TokioAsyncReadCompatExt;
use futures::io::AsyncReadExt;

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let listener = TcpListener::bind("127.0.0.1:8081").await?;

    tokio::spawn(async {
        let mut client = TcpStream::connect("127.0.0.1:8081").await.unwrap();
        client.write_all(b"Hello World").await.unwrap();
    });

    let (stream, _) = listener.accept().await?;

    // Adapt `tokio::TcpStream` to be used with `futures::io::AsyncReadExt`
    let mut compat_stream = stream.compat();
    let mut buffer = [0; 20];
    let n = compat_stream.read(&mut buffer).await?;
    println!("Received: {}", String::from_utf8_lossy(&buffer[..n]));

    Ok(())
}

§Example 2: Futures -> Tokio (AsyncRead)

The reverse is also possible: you can take a futures::io::AsyncRead (e.g. a cursor) and adapt it to be used with tokio::io::AsyncReadExt::read_to_end

use futures::io::Cursor;
use tokio_util::compat::FuturesAsyncReadCompatExt;
use tokio::io::AsyncReadExt;

fn main() {
    let future = async {
        let reader = Cursor::new(b"Hello from futures");
        let mut compat_reader = reader.compat();
        let mut buf = Vec::new();
        compat_reader.read_to_end(&mut buf).await.unwrap();
        assert_eq!(&buf, b"Hello from futures");
    };

    // Run the future inside a Tokio runtime
    tokio::runtime::Runtime::new().unwrap().block_on(future);
}

§Common Use Cases

  • Using tokio sockets with async-tungstenite, async-compression, or futures-rs-based libraries.
  • Bridging I/O interfaces between mixed-ecosystem libraries.
  • Avoiding rewrites or duplication of I/O code in async environments.

§See Also

Structs§

Compat
A compatibility layer that allows conversion between the tokio::io and futures-io AsyncRead and AsyncWrite traits.

Traits§

FuturesAsyncReadCompatExt
Extension trait that allows converting a type implementing futures_io::AsyncRead to implement tokio::io::AsyncRead.
FuturesAsyncWriteCompatExt
Extension trait that allows converting a type implementing futures_io::AsyncWrite to implement tokio::io::AsyncWrite.
TokioAsyncReadCompatExt
Extension trait that allows converting a type implementing tokio::io::AsyncRead to implement futures_io::AsyncRead.
TokioAsyncWriteCompatExt
Extension trait that allows converting a type implementing tokio::io::AsyncWrite to implement futures_io::AsyncWrite.