Repository: tokio-rs/tokio
File: tokio-util/src/io/sync_bridge.rs (Rust)

Code before:
/// ```rust
/// use tokio::io::AsyncReadExt;
/// use tokio::io::AsyncRead;
/// use std::io::Cursor;
/// # mod blake3 { pub fn hash(_: &[u8]) {} }
///
/// async fn hash_contents(mut reader: impl AsyncRead + Unpin) -> Result<(), std::io::Error> {
///    // Read all data from the reader into a Vec<u8>.
///    let mut data = Vec::new();
///    reader.read_to_end(&mut data).await?;
///
///    // Hash the data using the blake3 hashing function.
///    let hash = blake3::hash(&data);
///
///    Ok(())
///}
///
/// #[tokio::main]
/// async fn main() -> Result<(), std::io::Error> {
///     // Example: In-memory data.
///     let data = b"Hello, world!"; // A byte slice.
///     let reader = Cursor::new(data); // Create an in-memory AsyncRead.
///     hash_contents(reader).await
/// }
/// ```
/// Explanation: This example demonstrates how to asynchronously read data from a
/// reader into memory and hash it using a synchronous hashing function. The
/// `SyncIoBridge` is avoided, ensuring that the async runtime is not blocked.
///
///
/// When the data doesn't fit into memory, the hashing library will usually
/// provide a `hasher` that you can repeatedly call `update` on to hash the data
/// one chunk at the time. For example:
///
/// ```rust
/// use tokio::io::AsyncReadExt;
/// use tokio::io::AsyncRead;
/// use std::io::Cursor;
/// # struct Hasher;
/// # impl Hasher { pub fn update(&mut self, _: &[u8]) {} pub fn finalize(&self) {} }
///
/// /// Asynchronously streams data from an async reader, processes it in chunks,
/// /// and hashes the data incrementally.
/// async fn hash_stream(mut reader: impl AsyncRead + Unpin, mut hasher: Hasher) -> Result<(), std::io::Error> {
///    // Create a buffer to read data into, sized for performance.
///    let mut data = vec![0; 64 * 1024];
///    loop {
///        // Read data from the reader into the buffer.
///        let len = reader.read(&mut data).await?;
///        if len == 0 { break; } // Exit loop if no more data.
///

Review comment (suggestion):
For me the explanation of the code should be placed in front of the code so that you already know what the example does when reading it but that might just be my preference.

This goes for all the three examples.

Code after:
/// `SyncIoBridge` is avoided, ensuring that the async runtime is not blocked.
/// ```rust
/// use tokio::io::AsyncReadExt;
/// use tokio::io::AsyncRead;
/// use std::io::Cursor;
/// # mod blake3 { pub fn hash(_: &[u8]) {} }
///
/// async fn hash_contents(mut reader: impl AsyncRead + Unpin) -> Result<(), std::io::Error> {
///    // Read all data from the reader into a Vec<u8>.
///    let mut data = Vec::new();
///    reader.read_to_end(&mut data).await?;
///
///    // Hash the data using the blake3 hashing function.
///    let hash = blake3::hash(&data);
///
///    Ok(hash)
///}
///
/// #[tokio::main]
/// async fn main() -> Result<(), std::io::Error> {
///     // Example: In-memory data.
///     let data = b"Hello, world!"; // A byte slice.
///     let reader = Cursor::new(data); // Create an in-memory AsyncRead.
///     hash_contents(reader).await
/// }
/// ```
///
/// When the data doesn't fit into memory, the hashing library will usually
/// provide a `hasher` that you can repeatedly call `update` on to hash the data
/// one chunk at the time.
///
/// Explanation: This example demonstrates how to asynchronously stream data in
/// chunks for hashing. Each chunk is read asynchronously, and the hash is updated
/// incrementally. This avoids blocking and improves performance over using
/// `SyncIoBridge`.
///
/// ```rust
/// use tokio::io::AsyncReadExt;
/// use tokio::io::AsyncRead;
/// use std::io::Cursor;
/// # struct Hasher;
/// # impl Hasher { pub fn update(&mut self, _: &[u8]) {} pub fn finalize(&self) {} }
///
/// /// Asynchronously streams data from an async reader, processes it in chunks,
/// /// and hashes the data incrementally.
/// async fn hash_stream(mut reader: impl AsyncRead + Unpin, mut hasher: Hasher) -> Result<(), std::io::Error> {
///    // Create a buffer to read data into, sized for performance.
///    let mut data = vec![0; 64 * 1024];
///    loop {
///        // Read data from the reader into the buffer.
///        let len = reader.read(&mut data).await?;