docs: annotate io mod with doc_cfg (#1808)

Annotates types in `tokio::io` module with their required feature flag.
This annotation is included in generated documentation.

Notes:

* The annotation must be on the type or function itself. Annotating just
  the re-export is not sufficient.

* The annotation must be **inside** the `pin_project!` macro or it is
  lost.
This commit is contained in:
Carl Lerche
2019-11-22 09:56:08 -08:00
committed by GitHub
parent 8546ff826d
commit 9b2aa14bb1
34 changed files with 768 additions and 679 deletions
+1
View File
@@ -126,3 +126,4 @@ tempfile = "3.1.0"
[package.metadata.docs.rs] [package.metadata.docs.rs]
all-features = true all-features = true
rustdoc-args = ["--cfg", "docsrs"]
+15 -12
View File
@@ -10,6 +10,7 @@ use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::Relaxed; use std::sync::atomic::Ordering::Relaxed;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
cfg_io_driver! {
/// Associates an I/O resource that implements the [`std::io::Read`] and/or /// Associates an I/O resource that implements the [`std::io::Read`] and/or
/// [`std::io::Write`] traits with the reactor that drives it. /// [`std::io::Write`] traits with the reactor that drives it.
/// ///
@@ -18,23 +19,24 @@ use std::task::{Context, Poll};
/// [`std::io::Write`] and associate it with a reactor that will drive it. /// [`std::io::Write`] and associate it with a reactor that will drive it.
/// ///
/// Once the [`mio::Evented`] type is wrapped by `PollEvented`, it can be /// Once the [`mio::Evented`] type is wrapped by `PollEvented`, it can be
/// used from within the future's execution model. As such, the `PollEvented` /// used from within the future's execution model. As such, the
/// type provides [`AsyncRead`] and [`AsyncWrite`] implementations using the /// `PollEvented` type provides [`AsyncRead`] and [`AsyncWrite`]
/// underlying I/O resource as well as readiness events provided by the reactor. /// implementations using the underlying I/O resource as well as readiness
/// events provided by the reactor.
/// ///
/// **Note**: While `PollEvented` is `Sync` (if the underlying I/O type is /// **Note**: While `PollEvented` is `Sync` (if the underlying I/O type is
/// `Sync`), the caller must ensure that there are at most two tasks that use a /// `Sync`), the caller must ensure that there are at most two tasks that
/// `PollEvented` instance concurrently. One for reading and one for writing. /// use a `PollEvented` instance concurrently. One for reading and one for
/// While violating this requirement is "safe" from a Rust memory model point of /// writing. While violating this requirement is "safe" from a Rust memory
/// view, it will result in unexpected behavior in the form of lost /// model point of view, it will result in unexpected behavior in the form
/// notifications and tasks hanging. /// of lost notifications and tasks hanging.
/// ///
/// ## Readiness events /// ## Readiness events
/// ///
/// Besides just providing [`AsyncRead`] and [`AsyncWrite`] implementations, /// Besides just providing [`AsyncRead`] and [`AsyncWrite`] implementations,
/// this type also supports access to the underlying readiness event stream. /// this type also supports access to the underlying readiness event stream.
/// While similar in function to what [`Registration`] provides, the semantics /// While similar in function to what [`Registration`] provides, the
/// are a bit different. /// semantics are a bit different.
/// ///
/// Two functions are provided to access the readiness events: /// Two functions are provided to access the readiness events:
/// [`poll_read_ready`] and [`poll_write_ready`]. These functions return the /// [`poll_read_ready`] and [`poll_write_ready`]. These functions return the
@@ -44,8 +46,8 @@ use std::task::{Context, Poll};
/// ///
/// When the operation is attempted and is unable to succeed due to the I/O /// When the operation is attempted and is unable to succeed due to the I/O
/// resource not being ready, the caller must call [`clear_read_ready`] or /// resource not being ready, the caller must call [`clear_read_ready`] or
/// [`clear_write_ready`]. This clears the readiness state until a new readiness /// [`clear_write_ready`]. This clears the readiness state until a new
/// event is received. /// readiness event is received.
/// ///
/// This allows the caller to implement additional functions. For example, /// This allows the caller to implement additional functions. For example,
/// [`TcpListener`] implements poll_accept by using [`poll_read_ready`] and /// [`TcpListener`] implements poll_accept by using [`poll_read_ready`] and
@@ -103,6 +105,7 @@ pub struct PollEvented<E: Evented> {
io: Option<E>, io: Option<E>,
inner: Inner, inner: Inner,
} }
}
struct Inner { struct Inner {
registration: Registration, registration: Registration,
+14 -11
View File
@@ -5,6 +5,7 @@ use mio::{self, Evented};
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use std::io; use std::io;
cfg_io_driver! {
/// Associates an I/O resource with the reactor instance that drives it. /// Associates an I/O resource with the reactor instance that drives it.
/// ///
/// A registration represents an I/O resource registered with a Reactor such /// A registration represents an I/O resource registered with a Reactor such
@@ -15,22 +16,23 @@ use std::io;
/// the association is established, it remains established until the /// the association is established, it remains established until the
/// registration instance is dropped. /// registration instance is dropped.
/// ///
/// A registration instance represents two separate readiness streams. One for /// A registration instance represents two separate readiness streams. One
/// the read readiness and one for write readiness. These streams are /// for the read readiness and one for write readiness. These streams are
/// independent and can be consumed from separate tasks. /// independent and can be consumed from separate tasks.
/// ///
/// **Note**: while `Registration` is `Sync`, the caller must ensure that there /// **Note**: while `Registration` is `Sync`, the caller must ensure that
/// are at most two tasks that use a registration instance concurrently. One /// there are at most two tasks that use a registration instance
/// task for [`poll_read_ready`] and one task for [`poll_write_ready`]. While /// concurrently. One task for [`poll_read_ready`] and one task for
/// violating this requirement is "safe" from a Rust memory safety point of /// [`poll_write_ready`]. While violating this requirement is "safe" from a
/// view, it will result in unexpected behavior in the form of lost /// Rust memory safety point of view, it will result in unexpected behavior
/// notifications and tasks hanging. /// in the form of lost notifications and tasks hanging.
/// ///
/// ## Platform-specific events /// ## Platform-specific events
/// ///
/// `Registration` also allows receiving platform-specific `mio::Ready` events. /// `Registration` also allows receiving platform-specific `mio::Ready`
/// These events are included as part of the read readiness event stream. The /// events. These events are included as part of the read readiness event
/// write readiness event stream is only for `Ready::writable()` events. /// stream. The write readiness event stream is only for `Ready::writable()`
/// events.
/// ///
/// [`new`]: #method.new /// [`new`]: #method.new
/// [`poll_read_ready`]: #method.poll_read_ready`] /// [`poll_read_ready`]: #method.poll_read_ready`]
@@ -40,6 +42,7 @@ pub struct Registration {
handle: Handle, handle: Handle,
address: Address, address: Address,
} }
}
// ===== impl Registration ===== // ===== impl Registration =====
+11 -9
View File
@@ -16,6 +16,7 @@ use std::sync::atomic::Ordering::{Acquire, Release};
use std::sync::Arc; use std::sync::Arc;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
cfg_io_util! {
/// The readable half of a value returned from `split`. /// The readable half of a value returned from `split`.
pub struct ReadHalf<T> { pub struct ReadHalf<T> {
inner: Arc<Inner<T>>, inner: Arc<Inner<T>>,
@@ -26,15 +27,6 @@ pub struct WriteHalf<T> {
inner: Arc<Inner<T>>, inner: Arc<Inner<T>>,
} }
struct Inner<T> {
locked: AtomicBool,
stream: UnsafeCell<T>,
}
struct Guard<'a, T> {
inner: &'a Inner<T>,
}
/// 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.
/// ///
@@ -57,6 +49,16 @@ where
(rd, wr) (rd, wr)
} }
}
struct Inner<T> {
locked: AtomicBool,
stream: UnsafeCell<T>,
}
struct Guard<'a, T> {
inner: &'a Inner<T>,
}
impl<T> ReadHalf<T> { impl<T> ReadHalf<T> {
/// Reunite with a previously split `WriteHalf`. /// Reunite with a previously split `WriteHalf`.
+2
View File
@@ -6,6 +6,7 @@ use std::pin::Pin;
use std::task::Context; use std::task::Context;
use std::task::Poll; use std::task::Poll;
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 /// The handle implements the [`AsyncWrite`] trait, but beware that concurrent
@@ -30,6 +31,7 @@ pub fn stderr() -> Stderr {
std: Blocking::new(std), std: Blocking::new(std),
} }
} }
}
impl AsyncWrite for Stderr { impl AsyncWrite for Stderr {
fn poll_write( fn poll_write(
+2
View File
@@ -6,6 +6,7 @@ use std::pin::Pin;
use std::task::Context; use std::task::Context;
use std::task::Poll; use std::task::Poll;
cfg_io_std! {
/// A handle to the standard input stream of a process. /// A handle to the standard input stream of a process.
/// ///
/// The handle implements the [`AsyncRead`] trait, but beware that concurrent /// The handle implements the [`AsyncRead`] trait, but beware that concurrent
@@ -36,6 +37,7 @@ pub fn stdin() -> Stdin {
std: Blocking::new(std), std: Blocking::new(std),
} }
} }
}
impl AsyncRead for Stdin { impl AsyncRead for Stdin {
fn poll_read( fn poll_read(
+2
View File
@@ -6,6 +6,7 @@ use std::pin::Pin;
use std::task::Context; use std::task::Context;
use std::task::Poll; use std::task::Poll;
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 /// The handle implements the [`AsyncWrite`] trait, but beware that concurrent
@@ -30,6 +31,7 @@ pub fn stdout() -> Stdout {
std: Blocking::new(std), std: Blocking::new(std),
} }
} }
}
impl AsyncWrite for Stdout { impl AsyncWrite for Stdout {
fn poll_write( fn poll_write(
+2
View File
@@ -4,6 +4,7 @@ use crate::io::util::read_until::{read_until, ReadUntil};
use crate::io::util::split::{split, Split}; use crate::io::util::split::{split, Split};
use crate::io::AsyncBufRead; use crate::io::AsyncBufRead;
cfg_io_util! {
/// An extension trait which adds utility methods to `AsyncBufRead` types. /// An extension trait which adds utility methods to `AsyncBufRead` types.
pub trait AsyncBufReadExt: AsyncBufRead { pub trait AsyncBufReadExt: AsyncBufRead {
/// Creates a future which will read all the bytes associated with this I/O /// Creates a future which will read all the bytes associated with this I/O
@@ -118,5 +119,6 @@ pub trait AsyncBufReadExt: AsyncBufRead {
lines(self) lines(self)
} }
} }
}
impl<R: AsyncBufRead + ?Sized> AsyncBufReadExt for R {} impl<R: AsyncBufRead + ?Sized> AsyncBufReadExt for R {}
+2
View File
@@ -7,6 +7,7 @@ use crate::io::util::read_to_string::{read_to_string, ReadToString};
use crate::io::util::take::{take, Take}; use crate::io::util::take::{take, Take};
use crate::io::{AsyncRead, AsyncWrite}; use crate::io::{AsyncRead, AsyncWrite};
cfg_io_util! {
/// An extension trait which adds utility methods to `AsyncRead` types. /// An extension trait which adds utility methods to `AsyncRead` types.
pub trait AsyncReadExt: AsyncRead { pub trait AsyncReadExt: AsyncRead {
/// Creates an adaptor which will chain this stream with another. /// Creates an adaptor which will chain this stream with another.
@@ -88,5 +89,6 @@ pub trait AsyncReadExt: AsyncRead {
take(self, limit) take(self, limit)
} }
} }
}
impl<R: AsyncRead + ?Sized> AsyncReadExt for R {} impl<R: AsyncRead + ?Sized> AsyncReadExt for R {}
+2
View File
@@ -4,6 +4,7 @@ use crate::io::util::write::{write, Write};
use crate::io::util::write_all::{write_all, WriteAll}; use crate::io::util::write_all::{write_all, WriteAll};
use crate::io::AsyncWrite; use crate::io::AsyncWrite;
cfg_io_util! {
/// An extension trait which adds utility methods to `AsyncWrite` types. /// An extension trait which adds utility methods to `AsyncWrite` types.
pub trait AsyncWriteExt: AsyncWrite { pub trait AsyncWriteExt: AsyncWrite {
/// Write a buffer into this writter, returning how many bytes were written. /// Write a buffer into this writter, returning how many bytes were written.
@@ -38,5 +39,6 @@ pub trait AsyncWriteExt: AsyncWrite {
shutdown(self) shutdown(self)
} }
} }
}
impl<W: AsyncWrite + ?Sized> AsyncWriteExt for W {} impl<W: AsyncWrite + ?Sized> AsyncWriteExt for W {}
+1 -1
View File
@@ -24,7 +24,7 @@ pin_project! {
/// When the `BufReader` is dropped, the contents of its buffer will be /// When the `BufReader` is dropped, the contents of its buffer will be
/// discarded. Creating multiple instances of a `BufReader` on the same /// discarded. Creating multiple instances of a `BufReader` on the same
/// stream can cause data loss. /// stream can cause data loss.
// TODO: Examples #[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
pub struct BufReader<R> { pub struct BufReader<R> {
#[pin] #[pin]
pub(super) inner: R, pub(super) inner: R,
+1
View File
@@ -16,6 +16,7 @@ pin_project! {
/// types aid with these problems respectively, but do so in only one direction. `BufStream` wraps /// types aid with these problems respectively, but do so in only one direction. `BufStream` wraps
/// one in the other so that both directions are buffered. See their documentation for details. /// one in the other so that both directions are buffered. See their documentation for details.
#[derive(Debug)] #[derive(Debug)]
#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
pub struct BufStream<RW> { pub struct BufStream<RW> {
#[pin] #[pin]
inner: BufReader<BufWriter<RW>>, inner: BufReader<BufWriter<RW>>,
+1 -1
View File
@@ -29,7 +29,7 @@ pin_project! {
/// [`AsyncWrite`]: AsyncWrite /// [`AsyncWrite`]: AsyncWrite
/// [`flush`]: super::AsyncWriteExt::flush /// [`flush`]: super::AsyncWriteExt::flush
/// ///
// TODO: Examples #[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
pub struct BufWriter<W> { pub struct BufWriter<W> {
#[pin] #[pin]
pub(super) inner: W, pub(super) inner: W,
+1
View File
@@ -9,6 +9,7 @@ use std::task::{Context, Poll};
pin_project! { pin_project! {
/// Stream for the [`chain`](super::AsyncReadExt::chain) method. /// Stream for the [`chain`](super::AsyncReadExt::chain) method.
#[must_use = "streams do nothing unless polled"] #[must_use = "streams do nothing unless polled"]
#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
pub struct Chain<T, U> { pub struct Chain<T, U> {
#[pin] #[pin]
first: T, first: T,
+4 -2
View File
@@ -5,6 +5,7 @@ use std::io;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
cfg_io_util! {
/// A future that asynchronously copies the entire contents of a reader into a /// A future that asynchronously copies the entire contents of a reader into a
/// writer. /// writer.
/// ///
@@ -30,8 +31,8 @@ pub struct Copy<'a, R: ?Sized, W: ?Sized> {
/// `reader` and then write it into `writer` in a streaming fashion until /// `reader` and then write it into `writer` in a streaming fashion until
/// `reader` returns EOF. /// `reader` returns EOF.
/// ///
/// On success, the total number of bytes that were copied from /// On success, the total number of bytes that were copied from `reader` to
/// `reader` to `writer` is returned. /// `writer` is returned.
/// ///
/// This is an asynchronous version of [`std::io::copy`][std]. /// This is an asynchronous version of [`std::io::copy`][std].
/// ///
@@ -72,6 +73,7 @@ where
buf: Box::new([0; 2048]), buf: Box::new([0; 2048]),
} }
} }
}
impl<R, W> Future for Copy<'_, R, W> impl<R, W> Future for Copy<'_, R, W>
where where
+2
View File
@@ -5,6 +5,7 @@ use std::io;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
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
@@ -41,6 +42,7 @@ pub struct Empty {
pub fn empty() -> Empty { pub fn empty() -> Empty {
Empty { _p: () } Empty { _p: () }
} }
}
impl AsyncRead for Empty { impl AsyncRead for Empty {
#[inline] #[inline]
+2
View File
@@ -5,6 +5,7 @@ use std::io;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
cfg_io_util! {
/// A future used to fully flush an I/O object. /// A future used to fully flush an I/O object.
/// ///
/// Created by the [`AsyncWriteExt::flush`] function. /// Created by the [`AsyncWriteExt::flush`] function.
@@ -12,6 +13,7 @@ use std::task::{Context, Poll};
pub struct Flush<'a, A: ?Sized> { pub struct Flush<'a, A: ?Sized> {
a: &'a mut A, a: &'a mut A,
} }
}
/// Creates a future which will entirely flush an I/O object. /// Creates a future which will entirely flush an I/O object.
pub(super) fn flush<A>(a: &mut A) -> Flush<'_, A> pub(super) fn flush<A>(a: &mut A) -> Flush<'_, A>
+1
View File
@@ -11,6 +11,7 @@ pin_project! {
/// Stream for the [`lines`](crate::io::AsyncBufReadExt::lines) method. /// Stream for the [`lines`](crate::io::AsyncBufReadExt::lines) method.
#[derive(Debug)] #[derive(Debug)]
#[must_use = "streams do nothing unless polled"] #[must_use = "streams do nothing unless polled"]
#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
pub struct Lines<R> { pub struct Lines<R> {
#[pin] #[pin]
reader: R, reader: R,
+2
View File
@@ -18,6 +18,7 @@ where
Read { reader, buf } Read { reader, buf }
} }
cfg_io_util! {
/// A future which can be used to easily read available number of bytes to fill /// A future which can be used to easily read available number of bytes to fill
/// a buffer. /// a buffer.
/// ///
@@ -28,6 +29,7 @@ pub struct Read<'a, R: ?Sized> {
reader: &'a mut R, reader: &'a mut R,
buf: &'a mut [u8], buf: &'a mut [u8],
} }
}
impl<R> Future for Read<'_, R> impl<R> Future for Read<'_, R>
where where
+2
View File
@@ -21,6 +21,7 @@ where
} }
} }
cfg_io_util! {
/// Creates a future which will read exactly enough bytes to fill `buf`, /// Creates a future which will read exactly enough bytes to fill `buf`,
/// returning an error if EOF is hit sooner. /// returning an error if EOF is hit sooner.
/// ///
@@ -32,6 +33,7 @@ pub struct ReadExact<'a, A: ?Sized> {
buf: &'a mut [u8], buf: &'a mut [u8],
pos: usize, pos: usize,
} }
}
fn eof() -> io::Error { fn eof() -> io::Error {
io::Error::new(io::ErrorKind::UnexpectedEof, "early eof") io::Error::new(io::ErrorKind::UnexpectedEof, "early eof")
+2
View File
@@ -8,6 +8,7 @@ use std::pin::Pin;
use std::str; use std::str;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
cfg_io_util! {
/// Future for the [`read_line`](crate::io::AsyncBufReadExt::read_line) method. /// Future for the [`read_line`](crate::io::AsyncBufReadExt::read_line) method.
#[derive(Debug)] #[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"] #[must_use = "futures do nothing unless you `.await` or poll them"]
@@ -17,6 +18,7 @@ pub struct ReadLine<'a, R: ?Sized> {
bytes: Vec<u8>, bytes: Vec<u8>,
read: usize, read: usize,
} }
}
pub(crate) fn read_line<'a, R>(reader: &'a mut R, buf: &'a mut String) -> ReadLine<'a, R> pub(crate) fn read_line<'a, R>(reader: &'a mut R, buf: &'a mut String) -> ReadLine<'a, R>
where where
+1
View File
@@ -8,6 +8,7 @@ use std::task::{Context, Poll};
#[derive(Debug)] #[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"] #[must_use = "futures do nothing unless you `.await` or poll them"]
#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
pub struct ReadToEnd<'a, R: ?Sized> { pub struct ReadToEnd<'a, R: ?Sized> {
reader: &'a mut R, reader: &'a mut R,
buf: &'a mut Vec<u8>, buf: &'a mut Vec<u8>,
+2
View File
@@ -6,6 +6,7 @@ use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use std::{io, mem, str}; use std::{io, mem, str};
cfg_io_util! {
/// Future for the [`read_to_string`](super::AsyncReadExt::read_to_string) method. /// Future for the [`read_to_string`](super::AsyncReadExt::read_to_string) method.
#[derive(Debug)] #[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"] #[must_use = "futures do nothing unless you `.await` or poll them"]
@@ -15,6 +16,7 @@ pub struct ReadToString<'a, R: ?Sized> {
bytes: Vec<u8>, bytes: Vec<u8>,
start_len: usize, start_len: usize,
} }
}
pub(crate) fn read_to_string<'a, R>(reader: &'a mut R, buf: &'a mut String) -> ReadToString<'a, R> pub(crate) fn read_to_string<'a, R>(reader: &'a mut R, buf: &'a mut String) -> ReadToString<'a, R>
where where
+2
View File
@@ -6,6 +6,7 @@ use std::mem;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
cfg_io_util! {
/// Future for the [`read_until`](crate::io::AsyncBufReadExt::read_until) method. /// Future for the [`read_until`](crate::io::AsyncBufReadExt::read_until) method.
#[derive(Debug)] #[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"] #[must_use = "futures do nothing unless you `.await` or poll them"]
@@ -15,6 +16,7 @@ pub struct ReadUntil<'a, R: ?Sized> {
buf: &'a mut Vec<u8>, buf: &'a mut Vec<u8>,
read: usize, read: usize,
} }
}
pub(crate) fn read_until<'a, R>( pub(crate) fn read_until<'a, R>(
reader: &'a mut R, reader: &'a mut R,
+2
View File
@@ -4,6 +4,7 @@ use std::io;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
cfg_io_util! {
/// An async reader which yields one byte over and over and over and over and /// An async reader which yields one byte over and over and over and over and
/// over and... /// over and...
/// ///
@@ -41,6 +42,7 @@ pub struct Repeat {
pub fn repeat(byte: u8) -> Repeat { pub fn repeat(byte: u8) -> Repeat {
Repeat { byte } Repeat { byte }
} }
}
impl AsyncRead for Repeat { impl AsyncRead for Repeat {
#[inline] #[inline]
+2
View File
@@ -5,6 +5,7 @@ use std::io;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
cfg_io_util! {
/// A future used to shutdown an I/O object. /// A future used to shutdown an I/O object.
/// ///
/// Created by the [`AsyncWriteExt::shutdown`] function. /// Created by the [`AsyncWriteExt::shutdown`] function.
@@ -12,6 +13,7 @@ use std::task::{Context, Poll};
pub struct Shutdown<'a, A: ?Sized> { pub struct Shutdown<'a, A: ?Sized> {
a: &'a mut A, a: &'a mut A,
} }
}
/// Creates a future which will shutdown an I/O object. /// Creates a future which will shutdown an I/O object.
pub(super) fn shutdown<A>(a: &mut A) -> Shutdown<'_, A> pub(super) fn shutdown<A>(a: &mut A) -> Shutdown<'_, A>
+2
View File
@@ -5,6 +5,7 @@ use std::io;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
cfg_io_util! {
/// An async writer which will move data into the void. /// An async writer which will move data into the void.
/// ///
/// This struct is generally created by calling [`sink`][sink]. Please /// This struct is generally created by calling [`sink`][sink]. Please
@@ -39,6 +40,7 @@ pub struct Sink {
pub fn sink() -> Sink { pub fn sink() -> Sink {
Sink { _p: () } Sink { _p: () }
} }
}
impl AsyncWrite for Sink { impl AsyncWrite for Sink {
#[inline] #[inline]
+1
View File
@@ -11,6 +11,7 @@ pin_project! {
/// Stream for the [`split`](crate::io::AsyncBufReadExt::split) method. /// Stream for the [`split`](crate::io::AsyncBufReadExt::split) method.
#[derive(Debug)] #[derive(Debug)]
#[must_use = "streams do nothing unless polled"] #[must_use = "streams do nothing unless polled"]
#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
pub struct Split<R> { pub struct Split<R> {
#[pin] #[pin]
reader: R, reader: R,
+1
View File
@@ -10,6 +10,7 @@ pin_project! {
/// Stream for the [`take`](super::AsyncReadExt::take) method. /// Stream for the [`take`](super::AsyncReadExt::take) method.
#[derive(Debug)] #[derive(Debug)]
#[must_use = "streams do nothing unless you `.await` or poll them"] #[must_use = "streams do nothing unless you `.await` or poll them"]
#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
pub struct Take<R> { pub struct Take<R> {
#[pin] #[pin]
inner: R, inner: R,
+2
View File
@@ -5,6 +5,7 @@ use std::io;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
cfg_io_util! {
/// A future to write some of the buffer to an `AsyncWrite`. /// A future to write some of the buffer to an `AsyncWrite`.
#[derive(Debug)] #[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"] #[must_use = "futures do nothing unless you `.await` or poll them"]
@@ -12,6 +13,7 @@ pub struct Write<'a, W: ?Sized> {
writer: &'a mut W, writer: &'a mut W,
buf: &'a [u8], buf: &'a [u8],
} }
}
/// Tries to write some bytes from the given `buf` to the writer in an /// Tries to write some bytes from the given `buf` to the writer in an
/// asynchronous manner, returning a future. /// asynchronous manner, returning a future.
+2
View File
@@ -6,12 +6,14 @@ use std::mem;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
cfg_io_util! {
#[derive(Debug)] #[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"] #[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct WriteAll<'a, W: ?Sized> { pub struct WriteAll<'a, W: ?Sized> {
writer: &'a mut W, writer: &'a mut W,
buf: &'a [u8], buf: &'a [u8],
} }
}
pub(crate) fn write_all<'a, W>(writer: &'a mut W, buf: &'a [u8]) -> WriteAll<'a, W> pub(crate) fn write_all<'a, W>(writer: &'a mut W, buf: &'a [u8]) -> WriteAll<'a, W>
where where
+2 -1
View File
@@ -10,6 +10,7 @@
no_crate_inject, no_crate_inject,
attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables)) attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
))] ))]
#![cfg_attr(docsrs, feature(doc_cfg))]
//! A runtime for writing reliable, asynchronous, and slim applications. //! A runtime for writing reliable, asynchronous, and slim applications.
//! //!
@@ -71,7 +72,7 @@
//! [`tokio::task`]: crate::task //! [`tokio::task`]: crate::task
//! [`spawn`]: crate::task::spawn() //! [`spawn`]: crate::task::spawn()
//! [`JoinHandle`]: crate::task::JoinHandle //! [`JoinHandle`]: crate::task::JoinHandle
//! [`blocking`]: task/index.html#blocking-and-yielding //! [blocking]: task/index.html#blocking-and-yielding
//! //!
//! The [`tokio::sync`] module contains synchronization primitives to use when //! The [`tokio::sync`] module contains synchronization primitives to use when
//! need to communicate or share data. These include: //! need to communicate or share data. These include:
+38 -7
View File
@@ -12,7 +12,11 @@ macro_rules! cfg_resource_drivers {
macro_rules! cfg_blocking { macro_rules! cfg_blocking {
($($item:item)*) => { ($($item:item)*) => {
$( #[cfg(feature = "blocking")] $item )* $(
#[cfg(feature = "blocking")]
#[cfg_attr(docsrs, doc(cfg(feature = "blocking")))]
$item
)*
} }
} }
@@ -50,12 +54,22 @@ macro_rules! cfg_not_blocking_impl {
macro_rules! cfg_dns { macro_rules! cfg_dns {
($($item:item)*) => { ($($item:item)*) => {
$( #[cfg(feature = "dns")] $item )* $(
#[cfg(feature = "dns")]
#[cfg_attr(docsrs, doc(cfg(feature = "dns")))]
$item
)*
} }
} }
macro_rules! cfg_fs { macro_rules! cfg_fs {
($($item:item)*) => { $( #[cfg(feature = "fs")] $item )* } ($($item:item)*) => {
$(
#[cfg(feature = "fs")]
#[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
$item
)*
}
} }
macro_rules! cfg_io_blocking { macro_rules! cfg_io_blocking {
@@ -66,25 +80,40 @@ macro_rules! cfg_io_blocking {
macro_rules! cfg_io_driver { macro_rules! cfg_io_driver {
($($item:item)*) => { ($($item:item)*) => {
$( #[cfg(feature = "io-driver")] $item )* $(
#[cfg(feature = "io-driver")]
#[cfg_attr(docsrs, doc(cfg(feature = "io-driver")))]
$item
)*
} }
} }
macro_rules! cfg_not_io_driver { macro_rules! cfg_not_io_driver {
($($item:item)*) => { ($($item:item)*) => {
$( #[cfg(not(feature = "io-driver"))] $item )* $(
#[cfg(not(feature = "io-driver"))]
$item
)*
} }
} }
macro_rules! cfg_io_std { macro_rules! cfg_io_std {
($($item:item)*) => { ($($item:item)*) => {
$( #[cfg(feature = "io-std")] $item )* $(
#[cfg(feature = "io-std")]
#[cfg_attr(docsrs, doc(cfg(feature = "io-std")))]
$item
)*
} }
} }
macro_rules! cfg_io_util { macro_rules! cfg_io_util {
($($item:item)*) => { ($($item:item)*) => {
$( #[cfg(feature = "io-util")] $item )* $(
#[cfg(feature = "io-util")]
#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
$item
)*
} }
} }
@@ -110,6 +139,7 @@ macro_rules! cfg_macros {
($($item:item)*) => { ($($item:item)*) => {
$( $(
#[cfg(feature = "macros")] #[cfg(feature = "macros")]
#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
#[doc(inline)] #[doc(inline)]
$item $item
)* )*
@@ -120,6 +150,7 @@ macro_rules! cfg_process {
($($item:item)*) => { ($($item:item)*) => {
$( $(
#[cfg(feature = "process")] #[cfg(feature = "process")]
#[cfg_attr(docsrs, doc(cfg(feature = "process")))]
#[cfg(not(loom))] #[cfg(not(loom))]
$item $item
)* )*
+6 -2
View File
@@ -101,10 +101,14 @@
//! While similar to the standard library, this crate's `Child` type differs //! While similar to the standard library, this crate's `Child` type differs
//! importantly in the behavior of `drop`. In the standard library, a child //! importantly in the behavior of `drop`. In the standard library, a child
//! process will continue running after the instance of [`std::process::Child`] //! process will continue running after the instance of [`std::process::Child`]
//! is dropped. In this crate, however, because [`tokio::process::Child`][Child] is a //! is dropped. In this crate, however, because [`tokio::process::Child`] is a
//! future of the child's `ExitStatus`, a child process is terminated if //! future of the child's `ExitStatus`, a child process is terminated if
//! `tokio::process::Child` is dropped. The behavior of the standard library can //! `tokio::process::Child` is dropped. The behavior of the standard library can
//! be regained with the [`Child::forget`](crate::process::Child::forget) method. //! be regained with the [`Child::forget`](crate::process::Child::forget)
//! method.
//!
//! [`Command`]: crate::process::Command
//! [`tokio::process::Child`]: crate::process::Child
#[path = "unix/mod.rs"] #[path = "unix/mod.rs"]
#[cfg(unix)] #[cfg(unix)]