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

Code before:
use bytes::Bytes;
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`].
    /// Bytes are sent into the sink and the sink is flushed once all bytes are sent. If an error occurs during the sending progress,
    /// the number of sent but unflushed bytes are saved in case the flushing operation stays unsuccessful.
    /// For the inverse operation of defining an [`AsyncWrite`] from a [`Sink`] you need to define a [`codec`].
    ///
    /// # Example
    ///
    /// ```
    /// 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::<Vec<u8>>(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?;
    ///  // ... and receive it.
    ///  assert_eq!(data.to_vec(), rx.recv().await.unwrap());
    ///

Review comment (suggestion):
To make an actual newline in the generated documentation, you have to put an empty line in the doc-comment. So if you intended to have actual newlines, then you are missing some empty lines here. If you did _not_ intend to have actual newlines, then you should wrap each line at 80 characters instead of what you're doing here.

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> {