Skip to content

Commit a0af02a

Browse files
compat: add more documentation to tokio_util::compat (#7279)
1 parent 0ce3a11 commit a0af02a

File tree

2 files changed

+105
-2
lines changed

2 files changed

+105
-2
lines changed

tokio-util/src/compat.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,110 @@
11
//! Compatibility between the `tokio::io` and `futures-io` versions of the
22
//! `AsyncRead` and `AsyncWrite` traits.
3+
//!
4+
//! ## Bridging Tokio and Futures I/O with `compat()`
5+
//!
6+
//! The [`compat()`] function provides a compatibility layer that allows types implementing
7+
//! [`tokio::io::AsyncRead`] or [`tokio::io::AsyncWrite`] to be used as their
8+
//! [`futures::io::AsyncRead`] or [`futures::io::AsyncWrite`] counterparts — and vice versa.
9+
//!
10+
//! This is especially useful when working with libraries that expect I/O types from one ecosystem
11+
//! (usually `futures`) but you are using types from the other (usually `tokio`).
12+
//!
13+
//! ## Compatibility Overview
14+
//!
15+
//! | Inner Type Implements... | `Compat<T>` Implements... |
16+
//! |-----------------------------|-----------------------------|
17+
//! | [`tokio::io::AsyncRead`] | [`futures::io::AsyncRead`] |
18+
//! | [`futures::io::AsyncRead`] | [`tokio::io::AsyncRead`] |
19+
//! | [`tokio::io::AsyncWrite`] | [`futures::io::AsyncWrite`] |
20+
//! | [`futures::io::AsyncWrite`] | [`tokio::io::AsyncWrite`] |
21+
//!
22+
//! ## Feature Flag
23+
//!
24+
//! This functionality is available through the `compat` feature flag:
25+
//!
26+
//! ```toml
27+
//! tokio-util = { version = "...", features = ["compat"] }
28+
//! ```
29+
//!
30+
//! ## Example 1: Tokio -> Futures (`AsyncRead`)
31+
//!
32+
//! This example demonstrates sending data over a [`tokio::net::TcpStream`] and using
33+
//! [`futures::io::AsyncReadExt::read`] from the `futures` crate to read it after adapting the
34+
//! stream via [`compat()`].
35+
//!
36+
//! ```no_run
37+
//! use tokio::net::{TcpListener, TcpStream};
38+
//! use tokio::io::AsyncWriteExt;
39+
//! use tokio_util::compat::TokioAsyncReadCompatExt;
40+
//! use futures::io::AsyncReadExt;
41+
//!
42+
//! #[tokio::main]
43+
//! async fn main() -> std::io::Result<()> {
44+
//! let listener = TcpListener::bind("127.0.0.1:8081").await?;
45+
//!
46+
//! tokio::spawn(async {
47+
//! let mut client = TcpStream::connect("127.0.0.1:8081").await.unwrap();
48+
//! client.write_all(b"Hello World").await.unwrap();
49+
//! });
50+
//!
51+
//! let (stream, _) = listener.accept().await?;
52+
//!
53+
//! // Adapt `tokio::TcpStream` to be used with `futures::io::AsyncReadExt`
54+
//! let mut compat_stream = stream.compat();
55+
//! let mut buffer = [0; 20];
56+
//! let n = compat_stream.read(&mut buffer).await?;
57+
//! println!("Received: {}", String::from_utf8_lossy(&buffer[..n]));
58+
//!
59+
//! Ok(())
60+
//! }
61+
//! ```
62+
//!
63+
//! ## Example 2: Futures -> Tokio (`AsyncRead`)
64+
//!
65+
//! The reverse is also possible: you can take a [`futures::io::AsyncRead`] (e.g. a cursor) and
66+
//! adapt it to be used with [`tokio::io::AsyncReadExt::read_to_end`]
67+
//!
68+
//! ```
69+
//! use futures::io::Cursor;
70+
//! use tokio_util::compat::FuturesAsyncReadCompatExt;
71+
//! use tokio::io::AsyncReadExt;
72+
//!
73+
//! fn main() {
74+
//! let future = async {
75+
//! let reader = Cursor::new(b"Hello from futures");
76+
//! let mut compat_reader = reader.compat();
77+
//! let mut buf = Vec::new();
78+
//! compat_reader.read_to_end(&mut buf).await.unwrap();
79+
//! assert_eq!(&buf, b"Hello from futures");
80+
//! };
81+
//!
82+
//! // Run the future inside a Tokio runtime
83+
//! tokio::runtime::Runtime::new().unwrap().block_on(future);
84+
//! }
85+
//! ```
86+
//!
87+
//! ## Common Use Cases
88+
//!
89+
//! - Using `tokio` sockets with `async-tungstenite`, `async-compression`, or `futures-rs`-based
90+
//! libraries.
91+
//! - Bridging I/O interfaces between mixed-ecosystem libraries.
92+
//! - Avoiding rewrites or duplication of I/O code in async environments.
93+
//!
94+
//! ## See Also
95+
//!
96+
//! - [`Compat`] type
97+
//! - [`TokioAsyncReadCompatExt`]
98+
//! - [`FuturesAsyncReadCompatExt`]
99+
//! - [`tokio::io`]
100+
//! - [`futures::io`]
101+
//!
102+
//! [`futures::io`]: https://docs.rs/futures/latest/futures/io/
103+
//! [`futures::io::AsyncRead`]: https://docs.rs/futures/latest/futures/io/trait.AsyncRead.html
104+
//! [`futures::io::AsyncWrite`]: https://docs.rs/futures/latest/futures/io/trait.AsyncWrite.html
105+
//! [`futures::io::AsyncReadExt::read`]: https://docs.rs/futures/latest/futures/io/trait.AsyncReadExt.html#method.read
106+
//! [`compat()`]: TokioAsyncReadCompatExt::compat
107+
3108
use pin_project_lite::pin_project;
4109
use std::io;
5110
use std::pin::Pin;

tokio-util/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
//! This crate is not versioned in lockstep with the core
1717
//! [`tokio`] crate. However, `tokio-util` _will_ respect Rust's
1818
//! semantic versioning policy, especially with regard to breaking changes.
19-
//!
20-
//! [`tokio`]: https://docs.rs/tokio
2119
2220
#[macro_use]
2321
mod cfg;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy