mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-10-01 12:20:39 +00:00
docs: improve tokio::io API documentation (#2060)
* Links are added where missing and examples are improved. * Improve `stdin`, `stdout`, and `stderr` documentation by going into more details regarding what can go wrong in concurrent situations and provide examples for `stdout` and `stderr`.
This commit is contained in:
parent
45da5f3510
commit
780d6f91a0
@ -7,9 +7,15 @@ use std::task::{Context, Poll};
|
|||||||
|
|
||||||
/// Read bytes asynchronously.
|
/// Read bytes asynchronously.
|
||||||
///
|
///
|
||||||
/// This trait inherits from `std::io::BufRead` and indicates that an I/O object is
|
/// This trait inherits from [`std::io::BufRead`] and indicates that an I/O object is
|
||||||
/// **non-blocking**. All non-blocking I/O objects must return an error when
|
/// **non-blocking**. All non-blocking I/O objects must return an error when
|
||||||
/// bytes are unavailable instead of blocking the current thread.
|
/// bytes are unavailable instead of blocking the current thread.
|
||||||
|
///
|
||||||
|
/// Utilities for working with `AsyncBufRead` values are provided by
|
||||||
|
/// [`AsyncBufReadExt`].
|
||||||
|
///
|
||||||
|
/// [`std::io::BufRead`]: std::io::BufRead
|
||||||
|
/// [`AsyncBufReadExt`]: crate::io::AsyncBufReadExt
|
||||||
pub trait AsyncBufRead: AsyncRead {
|
pub trait AsyncBufRead: AsyncRead {
|
||||||
/// Attempt to return the contents of the internal buffer, filling it with more data
|
/// Attempt to return the contents of the internal buffer, filling it with more data
|
||||||
/// from the inner reader if it is empty.
|
/// from the inner reader if it is empty.
|
||||||
|
@ -5,9 +5,16 @@ use std::task::{Context, Poll};
|
|||||||
|
|
||||||
/// Seek bytes asynchronously.
|
/// Seek bytes asynchronously.
|
||||||
///
|
///
|
||||||
/// This trait is analogous to the `std::io::Seek` trait, but integrates
|
/// This trait is analogous to the [`std::io::Seek`] trait, but integrates
|
||||||
/// with the asynchronous task system. In particular, the `start_seek`
|
/// with the asynchronous task system. In particular, the `start_seek`
|
||||||
/// method, unlike `Seek::seek`, will not block the calling thread.
|
/// method, unlike [`Seek::seek`], will not block the calling thread.
|
||||||
|
///
|
||||||
|
/// Utilities for working with `AsyncSeek` values are provided by
|
||||||
|
/// [`AsyncSeekExt`].
|
||||||
|
///
|
||||||
|
/// [`std::io::Seek`]: std::io::Seek
|
||||||
|
/// [`Seek::seek`]: std::io::Seek::seek()
|
||||||
|
/// [`AsyncSeekExt`]: crate::io::AsyncSeekExt
|
||||||
pub trait AsyncSeek {
|
pub trait AsyncSeek {
|
||||||
/// Attempt to seek to an offset, in bytes, in a stream.
|
/// Attempt to seek to an offset, in bytes, in a stream.
|
||||||
///
|
///
|
||||||
|
@ -6,11 +6,11 @@ use std::task::{Context, Poll};
|
|||||||
|
|
||||||
/// Writes bytes asynchronously.
|
/// Writes bytes asynchronously.
|
||||||
///
|
///
|
||||||
/// The trait inherits from `std::io::Write` and indicates that an I/O object is
|
/// The trait inherits from [`std::io::Write`] and indicates that an I/O object is
|
||||||
/// **nonblocking**. All non-blocking I/O objects must return an error when
|
/// **nonblocking**. All non-blocking I/O objects must return an error when
|
||||||
/// bytes cannot be written instead of blocking the current thread.
|
/// bytes cannot be written instead of blocking the current thread.
|
||||||
///
|
///
|
||||||
/// Specifically, this means that the `poll_write` function will return one of
|
/// Specifically, this means that the [`poll_write`] function will return one of
|
||||||
/// the following:
|
/// the following:
|
||||||
///
|
///
|
||||||
/// * `Poll::Ready(Ok(n))` means that `n` bytes of data was immediately
|
/// * `Poll::Ready(Ok(n))` means that `n` bytes of data was immediately
|
||||||
@ -26,14 +26,23 @@ use std::task::{Context, Poll};
|
|||||||
/// * `Poll::Ready(Err(e))` for other errors are standard I/O errors coming from the
|
/// * `Poll::Ready(Err(e))` for other errors are standard I/O errors coming from the
|
||||||
/// underlying object.
|
/// underlying object.
|
||||||
///
|
///
|
||||||
/// This trait importantly means that the `write` method only works in the
|
/// This trait importantly means that the [`write`][stdwrite] method only works in
|
||||||
/// context of a future's task. The object may panic if used outside of a task.
|
/// the context of a future's task. The object may panic if used outside of a task.
|
||||||
///
|
///
|
||||||
/// Note that this trait also represents that the `Write::flush` method works
|
/// Note that this trait also represents that the [`Write::flush`][stdflush] method
|
||||||
/// very similarly to the `write` method, notably that `Ok(())` means that the
|
/// works very similarly to the `write` method, notably that `Ok(())` means that the
|
||||||
/// writer has successfully been flushed, a "would block" error means that the
|
/// writer has successfully been flushed, a "would block" error means that the
|
||||||
/// current task is ready to receive a notification when flushing can make more
|
/// current task is ready to receive a notification when flushing can make more
|
||||||
/// progress, and otherwise normal errors can happen as well.
|
/// progress, and otherwise normal errors can happen as well.
|
||||||
|
///
|
||||||
|
/// Utilities for working with `AsyncWrite` values are provided by
|
||||||
|
/// [`AsyncWriteExt`].
|
||||||
|
///
|
||||||
|
/// [`std::io::Write`]: std::io::Write
|
||||||
|
/// [`poll_write`]: AsyncWrite::poll_write()
|
||||||
|
/// [stdwrite]: std::io::Write::write()
|
||||||
|
/// [stdflush]: std::io::Write::flush()
|
||||||
|
/// [`AsyncWriteExt`]: crate::io::AsyncWriteExt
|
||||||
pub trait AsyncWrite {
|
pub trait AsyncWrite {
|
||||||
/// Attempt to write bytes from `buf` into the object.
|
/// Attempt to write bytes from `buf` into the object.
|
||||||
///
|
///
|
||||||
|
@ -17,12 +17,12 @@ use std::sync::Arc;
|
|||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
cfg_io_util! {
|
cfg_io_util! {
|
||||||
/// The readable half of a value returned from `split`.
|
/// The readable half of a value returned from [`split`](split()).
|
||||||
pub struct ReadHalf<T> {
|
pub struct ReadHalf<T> {
|
||||||
inner: Arc<Inner<T>>,
|
inner: Arc<Inner<T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The writable half of a value returned from `split`.
|
/// The writable half of a value returned from [`split`](split()).
|
||||||
pub struct WriteHalf<T> {
|
pub struct WriteHalf<T> {
|
||||||
inner: Arc<Inner<T>>,
|
inner: Arc<Inner<T>>,
|
||||||
}
|
}
|
||||||
@ -30,8 +30,8 @@ cfg_io_util! {
|
|||||||
/// Split a single value implementing `AsyncRead + AsyncWrite` into separate
|
/// Split a single value implementing `AsyncRead + AsyncWrite` into separate
|
||||||
/// `AsyncRead` and `AsyncWrite` handles.
|
/// `AsyncRead` and `AsyncWrite` handles.
|
||||||
///
|
///
|
||||||
/// To restore this read/write object from its `split::ReadHalf` and
|
/// To restore this read/write object from its `ReadHalf` and
|
||||||
/// `split::WriteHalf` use `unsplit`.
|
/// `WriteHalf` use [`unsplit`](ReadHalf::unsplit()).
|
||||||
pub fn split<T>(stream: T) -> (ReadHalf<T>, WriteHalf<T>)
|
pub fn split<T>(stream: T) -> (ReadHalf<T>, WriteHalf<T>)
|
||||||
where
|
where
|
||||||
T: AsyncRead + AsyncWrite,
|
T: AsyncRead + AsyncWrite,
|
||||||
|
@ -9,13 +9,30 @@ use std::task::Poll;
|
|||||||
cfg_io_std! {
|
cfg_io_std! {
|
||||||
/// A handle to the standard error stream of a process.
|
/// A handle to the standard error stream of a process.
|
||||||
///
|
///
|
||||||
/// The handle implements the [`AsyncWrite`] trait, but beware that concurrent
|
/// Concurrent writes to stderr must be executed with care: Only individual
|
||||||
/// writes to `Stderr` must be executed with care.
|
/// writes to this [`AsyncWrite`] are guaranteed to be intact. In particular
|
||||||
|
/// you should be aware that writes using [`write_all`] are not guaranteed
|
||||||
|
/// to occur as a single write, so multiple threads writing data with
|
||||||
|
/// [`write_all`] may result in interleaved output.
|
||||||
///
|
///
|
||||||
/// Created by the [`stderr`] function.
|
/// Created by the [`stderr`] function.
|
||||||
///
|
///
|
||||||
/// [`stderr`]: stderr()
|
/// [`stderr`]: stderr()
|
||||||
/// [`AsyncWrite`]: AsyncWrite
|
/// [`AsyncWrite`]: AsyncWrite
|
||||||
|
/// [`write_all`]: crate::io::AsyncWriteExt::write_all()
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use tokio::io::{self, AsyncWriteExt};
|
||||||
|
///
|
||||||
|
/// #[tokio::main]
|
||||||
|
/// async fn main() -> io::Result<()> {
|
||||||
|
/// let mut stderr = io::stdout();
|
||||||
|
/// stderr.write_all(b"Print some error here.").await?;
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Stderr {
|
pub struct Stderr {
|
||||||
std: Blocking<std::io::Stderr>,
|
std: Blocking<std::io::Stderr>,
|
||||||
@ -25,6 +42,28 @@ cfg_io_std! {
|
|||||||
///
|
///
|
||||||
/// The returned handle allows writing to standard error from the within the
|
/// The returned handle allows writing to standard error from the within the
|
||||||
/// Tokio runtime.
|
/// Tokio runtime.
|
||||||
|
///
|
||||||
|
/// Concurrent writes to stderr must be executed with care: Only individual
|
||||||
|
/// writes to this [`AsyncWrite`] are guaranteed to be intact. In particular
|
||||||
|
/// you should be aware that writes using [`write_all`] are not guaranteed
|
||||||
|
/// to occur as a single write, so multiple threads writing data with
|
||||||
|
/// [`write_all`] may result in interleaved output.
|
||||||
|
///
|
||||||
|
/// [`AsyncWrite`]: AsyncWrite
|
||||||
|
/// [`write_all`]: crate::io::AsyncWriteExt::write_all()
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use tokio::io::{self, AsyncWriteExt};
|
||||||
|
///
|
||||||
|
/// #[tokio::main]
|
||||||
|
/// async fn main() -> io::Result<()> {
|
||||||
|
/// let mut stderr = io::stdout();
|
||||||
|
/// stderr.write_all(b"Print some error here.").await?;
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub fn stderr() -> Stderr {
|
pub fn stderr() -> Stderr {
|
||||||
let std = io::stderr();
|
let std = io::stderr();
|
||||||
Stderr {
|
Stderr {
|
||||||
|
@ -13,7 +13,7 @@ cfg_io_std! {
|
|||||||
/// reads of `Stdin` must be executed with care.
|
/// reads of `Stdin` must be executed with care.
|
||||||
///
|
///
|
||||||
/// As an additional caveat, reading from the handle may block the calling
|
/// As an additional caveat, reading from the handle may block the calling
|
||||||
/// future indefinitely, if there is not enough data available. This makes this
|
/// future indefinitely if there is not enough data available. This makes this
|
||||||
/// handle unsuitable for use in any circumstance where immediate reaction to
|
/// handle unsuitable for use in any circumstance where immediate reaction to
|
||||||
/// available data is required, e.g. interactive use or when implementing a
|
/// available data is required, e.g. interactive use or when implementing a
|
||||||
/// subprocess driven by requests on the standard input.
|
/// subprocess driven by requests on the standard input.
|
||||||
@ -31,6 +31,12 @@ cfg_io_std! {
|
|||||||
///
|
///
|
||||||
/// The returned handle allows reading from standard input from the within the
|
/// The returned handle allows reading from standard input from the within the
|
||||||
/// Tokio runtime.
|
/// Tokio runtime.
|
||||||
|
///
|
||||||
|
/// As an additional caveat, reading from the handle may block the calling
|
||||||
|
/// future indefinitely if there is not enough data available. This makes this
|
||||||
|
/// handle unsuitable for use in any circumstance where immediate reaction to
|
||||||
|
/// available data is required, e.g. interactive use or when implementing a
|
||||||
|
/// subprocess driven by requests on the standard input.
|
||||||
pub fn stdin() -> Stdin {
|
pub fn stdin() -> Stdin {
|
||||||
let std = io::stdin();
|
let std = io::stdin();
|
||||||
Stdin {
|
Stdin {
|
||||||
|
@ -9,13 +9,30 @@ use std::task::Poll;
|
|||||||
cfg_io_std! {
|
cfg_io_std! {
|
||||||
/// A handle to the standard output stream of a process.
|
/// A handle to the standard output stream of a process.
|
||||||
///
|
///
|
||||||
/// The handle implements the [`AsyncWrite`] trait, but beware that concurrent
|
/// Concurrent writes to stdout must be executed with care: Only individual
|
||||||
/// writes to `Stdout` must be executed with care.
|
/// writes to this [`AsyncWrite`] are guaranteed to be intact. In particular
|
||||||
|
/// you should be aware that writes using [`write_all`] are not guaranteed
|
||||||
|
/// to occur as a single write, so multiple threads writing data with
|
||||||
|
/// [`write_all`] may result in interleaved output.
|
||||||
///
|
///
|
||||||
/// Created by the [`stdout`] function.
|
/// Created by the [`stdout`] function.
|
||||||
///
|
///
|
||||||
/// [`stdout`]: fn.stdout.html
|
/// [`stdout`]: stdout()
|
||||||
/// [`AsyncWrite`]: trait.AsyncWrite.html
|
/// [`AsyncWrite`]: AsyncWrite
|
||||||
|
/// [`write_all`]: crate::io::AsyncWriteExt::write_all()
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use tokio::io::{self, AsyncWriteExt};
|
||||||
|
///
|
||||||
|
/// #[tokio::main]
|
||||||
|
/// async fn main() -> io::Result<()> {
|
||||||
|
/// let mut stdout = io::stdout();
|
||||||
|
/// stdout.write_all(b"Hello world!").await?;
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Stdout {
|
pub struct Stdout {
|
||||||
std: Blocking<std::io::Stdout>,
|
std: Blocking<std::io::Stdout>,
|
||||||
@ -23,8 +40,30 @@ cfg_io_std! {
|
|||||||
|
|
||||||
/// Constructs a new handle to the standard output of the current process.
|
/// Constructs a new handle to the standard output of the current process.
|
||||||
///
|
///
|
||||||
/// The returned handle allows writing to standard out from the within the Tokio
|
/// The returned handle allows writing to standard out from the within the
|
||||||
/// runtime.
|
/// Tokio runtime.
|
||||||
|
///
|
||||||
|
/// Concurrent writes to stdout must be executed with care: Only individual
|
||||||
|
/// writes to this [`AsyncWrite`] are guaranteed to be intact. In particular
|
||||||
|
/// you should be aware that writes using [`write_all`] are not guaranteed
|
||||||
|
/// to occur as a single write, so multiple threads writing data with
|
||||||
|
/// [`write_all`] may result in interleaved output.
|
||||||
|
///
|
||||||
|
/// [`AsyncWrite`]: AsyncWrite
|
||||||
|
/// [`write_all`]: crate::io::AsyncWriteExt::write_all()
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use tokio::io::{self, AsyncWriteExt};
|
||||||
|
///
|
||||||
|
/// #[tokio::main]
|
||||||
|
/// async fn main() -> io::Result<()> {
|
||||||
|
/// let mut stdout = io::stdout();
|
||||||
|
/// stdout.write_all(b"Hello world!").await?;
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub fn stdout() -> Stdout {
|
pub fn stdout() -> Stdout {
|
||||||
let std = io::stdout();
|
let std = io::stdout();
|
||||||
Stdout {
|
Stdout {
|
||||||
|
@ -5,7 +5,9 @@ use crate::io::util::split::{split, Split};
|
|||||||
use crate::io::AsyncBufRead;
|
use crate::io::AsyncBufRead;
|
||||||
|
|
||||||
cfg_io_util! {
|
cfg_io_util! {
|
||||||
/// An extension trait which adds utility methods to `AsyncBufRead` types.
|
/// An extension trait which adds utility methods to [`AsyncBufRead`] types.
|
||||||
|
///
|
||||||
|
/// [`AsyncBufRead`]: crate::io::AsyncBufRead
|
||||||
pub trait AsyncBufReadExt: AsyncBufRead {
|
pub trait AsyncBufReadExt: AsyncBufRead {
|
||||||
/// Read all bytes into `buf` until the delimiter `byte` or EOF is reached.
|
/// Read all bytes into `buf` until the delimiter `byte` or EOF is reached.
|
||||||
///
|
///
|
||||||
|
@ -36,6 +36,8 @@ cfg_io_util! {
|
|||||||
///
|
///
|
||||||
/// This is an asynchronous version of [`std::io::copy`][std].
|
/// This is an asynchronous version of [`std::io::copy`][std].
|
||||||
///
|
///
|
||||||
|
/// [std]: std::io::copy
|
||||||
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// The returned future will finish with an error will return an error
|
/// The returned future will finish with an error will return an error
|
||||||
@ -56,8 +58,6 @@ cfg_io_util! {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
|
||||||
/// [std]: std::io::copy
|
|
||||||
pub fn copy<'a, R, W>(reader: &'a mut R, writer: &'a mut W) -> Copy<'a, R, W>
|
pub fn copy<'a, R, W>(reader: &'a mut R, writer: &'a mut W) -> Copy<'a, R, W>
|
||||||
where
|
where
|
||||||
R: AsyncRead + Unpin + ?Sized,
|
R: AsyncRead + Unpin + ?Sized,
|
||||||
|
@ -6,7 +6,7 @@ use std::pin::Pin;
|
|||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
cfg_io_util! {
|
cfg_io_util! {
|
||||||
// An async reader which is always at EOF.
|
/// An async reader which is always at EOF.
|
||||||
///
|
///
|
||||||
/// This struct is generally created by calling [`empty`]. Please see
|
/// This struct is generally created by calling [`empty`]. Please see
|
||||||
/// the documentation of [`empty()`][`empty`] for more details.
|
/// the documentation of [`empty()`][`empty`] for more details.
|
||||||
@ -14,7 +14,7 @@ cfg_io_util! {
|
|||||||
/// This is an asynchronous version of [`std::io::empty`][std].
|
/// This is an asynchronous version of [`std::io::empty`][std].
|
||||||
///
|
///
|
||||||
/// [`empty`]: fn.empty.html
|
/// [`empty`]: fn.empty.html
|
||||||
/// [std]: https://doc.rust-lang.org/std/io/struct.Empty.html
|
/// [std]: std::io::empty
|
||||||
pub struct Empty {
|
pub struct Empty {
|
||||||
_p: (),
|
_p: (),
|
||||||
}
|
}
|
||||||
@ -25,20 +25,22 @@ cfg_io_util! {
|
|||||||
///
|
///
|
||||||
/// This is an asynchronous version of [`std::io::empty`][std].
|
/// This is an asynchronous version of [`std::io::empty`][std].
|
||||||
///
|
///
|
||||||
|
/// [std]: std::io::empty
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// A slightly sad example of not reading anything into a buffer:
|
/// A slightly sad example of not reading anything into a buffer:
|
||||||
///
|
///
|
||||||
/// ```rust
|
|
||||||
/// # use tokio::io::{self, AsyncReadExt};
|
|
||||||
/// # async fn dox() {
|
|
||||||
/// let mut buffer = String::new();
|
|
||||||
/// io::empty().read_to_string(&mut buffer).await.unwrap();
|
|
||||||
/// assert!(buffer.is_empty());
|
|
||||||
/// # }
|
|
||||||
/// ```
|
/// ```
|
||||||
|
/// use tokio::io::{self, AsyncReadExt};
|
||||||
///
|
///
|
||||||
/// [std]: https://doc.rust-lang.org/std/io/fn.empty.html
|
/// #[tokio::main]
|
||||||
|
/// async fn main() {
|
||||||
|
/// let mut buffer = String::new();
|
||||||
|
/// io::empty().read_to_string(&mut buffer).await.unwrap();
|
||||||
|
/// assert!(buffer.is_empty());
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub fn empty() -> Empty {
|
pub fn empty() -> Empty {
|
||||||
Empty { _p: () }
|
Empty { _p: () }
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ cfg_io_util! {
|
|||||||
/// This is an asynchronous version of [`std::io::Repeat`][std].
|
/// This is an asynchronous version of [`std::io::Repeat`][std].
|
||||||
///
|
///
|
||||||
/// [repeat]: fn.repeat.html
|
/// [repeat]: fn.repeat.html
|
||||||
/// [std]: https://doc.rust-lang.org/std/io/struct.Repeat.html
|
/// [std]: std::io::Repeat
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Repeat {
|
pub struct Repeat {
|
||||||
byte: u8,
|
byte: u8,
|
||||||
@ -27,18 +27,20 @@ cfg_io_util! {
|
|||||||
///
|
///
|
||||||
/// This is an asynchronous version of [`std::io::repeat`][std].
|
/// This is an asynchronous version of [`std::io::repeat`][std].
|
||||||
///
|
///
|
||||||
|
/// [std]: std::io::repeat
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use tokio::io::{self, AsyncReadExt};
|
/// use tokio::io::{self, AsyncReadExt};
|
||||||
/// # async fn dox() {
|
|
||||||
/// let mut buffer = [0; 3];
|
|
||||||
/// io::repeat(0b101).read_exact(&mut buffer).await.unwrap();
|
|
||||||
/// assert_eq!(buffer, [0b101, 0b101, 0b101]);
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
///
|
///
|
||||||
/// [std]: https://doc.rust-lang.org/std/io/fn.repeat.html
|
/// #[tokio::main]
|
||||||
|
/// async fn main() {
|
||||||
|
/// let mut buffer = [0; 3];
|
||||||
|
/// io::repeat(0b101).read_exact(&mut buffer).await.unwrap();
|
||||||
|
/// assert_eq!(buffer, [0b101, 0b101, 0b101]);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub fn repeat(byte: u8) -> Repeat {
|
pub fn repeat(byte: u8) -> Repeat {
|
||||||
Repeat { byte }
|
Repeat { byte }
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,10 @@ cfg_io_util! {
|
|||||||
/// This struct is generally created by calling [`sink`][sink]. Please
|
/// This struct is generally created by calling [`sink`][sink]. Please
|
||||||
/// see the documentation of `sink()` for more details.
|
/// see the documentation of `sink()` for more details.
|
||||||
///
|
///
|
||||||
/// This is an asynchronous version of `std::io::Sink`.
|
/// This is an asynchronous version of [`std::io::Sink`][std].
|
||||||
///
|
///
|
||||||
/// [sink]: fn.sink.html
|
/// [sink]: sink()
|
||||||
|
/// [std]: std::io::Sink
|
||||||
pub struct Sink {
|
pub struct Sink {
|
||||||
_p: (),
|
_p: (),
|
||||||
}
|
}
|
||||||
@ -21,21 +22,27 @@ cfg_io_util! {
|
|||||||
/// Creates an instance of an async writer which will successfully consume all
|
/// Creates an instance of an async writer which will successfully consume all
|
||||||
/// data.
|
/// data.
|
||||||
///
|
///
|
||||||
/// All calls to `poll_write` on the returned instance will return
|
/// All calls to [`poll_write`] on the returned instance will return
|
||||||
/// `Poll::Ready(Ok(buf.len()))` and the contents of the buffer will not be
|
/// `Poll::Ready(Ok(buf.len()))` and the contents of the buffer will not be
|
||||||
/// inspected.
|
/// inspected.
|
||||||
///
|
///
|
||||||
/// This is an asynchronous version of `std::io::sink`.
|
/// This is an asynchronous version of [`std::io::sink`][std].
|
||||||
|
///
|
||||||
|
/// [`poll_write`]: crate::io::AsyncWrite::poll_write()
|
||||||
|
/// [std]: std::io::sink
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```
|
||||||
/// # use tokio::io::{self, AsyncWriteExt};
|
/// use tokio::io::{self, AsyncWriteExt};
|
||||||
/// # async fn dox() {
|
///
|
||||||
/// let buffer = vec![1, 2, 3, 5, 8];
|
/// #[tokio::main]
|
||||||
/// let num_bytes = io::sink().write(&buffer).await.unwrap();
|
/// async fn main() -> io::Result<()> {
|
||||||
/// assert_eq!(num_bytes, 5);
|
/// let buffer = vec![1, 2, 3, 5, 8];
|
||||||
/// # }
|
/// let num_bytes = io::sink().write(&buffer).await?;
|
||||||
|
/// assert_eq!(num_bytes, 5);
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn sink() -> Sink {
|
pub fn sink() -> Sink {
|
||||||
Sink { _p: () }
|
Sink { _p: () }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user