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

Code before:
use futures_sink::Sink;

use pin_project_lite::pin_project;
use std::io;
use std::pin::Pin;
use std::task::{Context, Poll};
use tokio::io::AsyncWrite;

pin_project! {
    /// Convert a [`Sink`] of byte chunks into an [`AsyncWrite`].
    ///
    /// Whenever you write to this [`SinkWriter`], the supplied bytes are
    /// forwarded to the inner [`Sink`]. When `shutdown` is called on this
    /// [`SinkWriter`], the inner sink is closed.
    ///
    /// This adapter implements [`AsyncWrite`] for `Sink<&[u8]>`. If you want to
    /// implement `Sink<_>` for [`AsyncWrite`], see the [`codec`] module; if you need to implement
    /// [`AsyncWrite`] for `Sink<Bytes>`, see [`CopyToBytes`].
    ///
    /// # Example
    ///
    /// ```
    /// use bytes::Bytes;
    /// use futures_util::SinkExt;
    /// use std::io::{Error, ErrorKind};
    /// use tokio::io::AsyncWriteExt;
    /// use tokio_util::io::{SinkWriter, CopyToBytes};
    /// use tokio_util::sync::PollSender;
    ///
    /// # #[tokio::main]
    /// # async fn main() -> Result<(), Error> {
    /// // Construct a channel pair to send data across and wrap a pollable sink.
    /// // Note that the sink must mimic a writable object, e.g. have `std::io::Error`
    /// // as its error type.
    /// let (tx, mut rx) = tokio::sync::mpsc::channel::<Bytes>(1);
    /// let mut writer = SinkWriter::new(CopyToBytes::new(
    ///   PollSender::new(tx).sink_map_err(|_| Error::from(ErrorKind::BrokenPipe)),
    /// ));
    ///
    /// // Write data to our interface...
    /// let data: [u8; 4] = [1, 2, 3, 4];
    /// let _ = writer.write(&data).await?;
    ///

Review comment (suggestion):
```suggestion
    /// This adapter implements [`AsyncWrite`] for `Sink<&[u8]>`. Because of the
    /// lifetime, this trait is relatively rarely implemented. The main ways to
    /// get a `Sink<&[u8]>` that you can use with this type are:
    ///
    ///  * With the codec module by implementing the [`Encoder<&[u8]>`] trait.
    ///  * By wrapping a `Sink<Bytes>` in a [`CopyToBytes`].
    ///  * Manually implementing `Sink<&[u8]>` directly.
    ///
    /// The opposite conversion of implementing `Sink<_>` for an [`AsyncWrite`]
    /// is done using the [`codec`] module.
    ///
    /// [`Encoder<&[u8]>`]: crate::codec::Encoder
```


Code after:
use futures_sink::Sink;

use pin_project_lite::pin_project;
use std::io;
use std::pin::Pin;
use std::task::{Context, Poll};
use tokio::io::AsyncWrite;

pin_project! {
    /// Convert a [`Sink`] of byte chunks into an [`AsyncWrite`].
    ///
    /// Whenever you write to this [`SinkWriter`], the supplied bytes are
    /// forwarded to the inner [`Sink`]. When `shutdown` is called on this
    /// [`SinkWriter`], the inner sink is closed.
    ///
    /// This adapter takes a `Sink<&[u8]>` and provides an [`AsyncWrite`] impl
    /// for it. Because of the lifetime, this trait is relatively rarely
    /// implemented. The main ways to get a `Sink<&[u8]>` that you can use with
    /// this type are:
    ///
    ///  * With the codec module by implementing the [`Encoder`]`<&[u8]>` trait.
    ///  * By wrapping a `Sink<Bytes>` in a [`CopyToBytes`].
    ///  * Manually implementing `Sink<&[u8]>` directly.
    ///
    /// The opposite conversion of implementing `Sink<_>` for an [`AsyncWrite`]
    /// is done using the [`codec`] module.
    ///
    /// # Example
    ///
    /// ```
    /// use bytes::Bytes;
    /// use futures_util::SinkExt;
    /// use std::io::{Error, ErrorKind};
    /// use tokio::io::AsyncWriteExt;
    /// use tokio_util::io::{SinkWriter, CopyToBytes};
    /// use tokio_util::sync::PollSender;
    ///
    /// # #[tokio::main(flavor = "current_thread")]
    /// # async fn main() -> Result<(), Error> {
    /// // We use an mpsc channel as an example of a `Sink<Bytes>`.
    /// let (tx, mut rx) = tokio::sync::mpsc::channel::<Bytes>(1);
    /// let sink = PollSender::new(tx).sink_map_err(|_| Error::from(ErrorKind::BrokenPipe));
    ///