mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-16 00:00:12 +02:00
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:
@@ -126,3 +126,4 @@ tempfile = "3.1.0"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
@@ -10,98 +10,101 @@ use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::atomic::Ordering::Relaxed;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
/// Associates an I/O resource that implements the [`std::io::Read`] and/or
|
||||
/// [`std::io::Write`] traits with the reactor that drives it.
|
||||
///
|
||||
/// `PollEvented` uses [`Registration`] internally to take a type that
|
||||
/// implements [`mio::Evented`] as well as [`std::io::Read`] and or
|
||||
/// [`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
|
||||
/// used from within the future's execution model. As such, the `PollEvented`
|
||||
/// type provides [`AsyncRead`] and [`AsyncWrite`] 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
|
||||
/// `Sync`), the caller must ensure that there are at most two tasks that use a
|
||||
/// `PollEvented` instance concurrently. One for reading and one for writing.
|
||||
/// While violating this requirement is "safe" from a Rust memory model point of
|
||||
/// view, it will result in unexpected behavior in the form of lost
|
||||
/// notifications and tasks hanging.
|
||||
///
|
||||
/// ## Readiness events
|
||||
///
|
||||
/// Besides just providing [`AsyncRead`] and [`AsyncWrite`] implementations,
|
||||
/// this type also supports access to the underlying readiness event stream.
|
||||
/// While similar in function to what [`Registration`] provides, the semantics
|
||||
/// are a bit different.
|
||||
///
|
||||
/// Two functions are provided to access the readiness events:
|
||||
/// [`poll_read_ready`] and [`poll_write_ready`]. These functions return the
|
||||
/// current readiness state of the `PollEvented` instance. If
|
||||
/// [`poll_read_ready`] indicates read readiness, immediately calling
|
||||
/// [`poll_read_ready`] again will also indicate read readiness.
|
||||
///
|
||||
/// 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
|
||||
/// [`clear_write_ready`]. This clears the readiness state until a new readiness
|
||||
/// event is received.
|
||||
///
|
||||
/// This allows the caller to implement additional functions. For example,
|
||||
/// [`TcpListener`] implements poll_accept by using [`poll_read_ready`] and
|
||||
/// [`clear_read_ready`].
|
||||
///
|
||||
/// ```rust
|
||||
/// use tokio::io::PollEvented;
|
||||
///
|
||||
/// use futures::ready;
|
||||
/// use mio::Ready;
|
||||
/// use mio::net::{TcpStream, TcpListener};
|
||||
/// use std::io;
|
||||
/// use std::task::{Context, Poll};
|
||||
///
|
||||
/// struct MyListener {
|
||||
/// poll_evented: PollEvented<TcpListener>,
|
||||
/// }
|
||||
///
|
||||
/// impl MyListener {
|
||||
/// pub fn poll_accept(&mut self, cx: &mut Context<'_>) -> Poll<Result<TcpStream, io::Error>> {
|
||||
/// let ready = Ready::readable();
|
||||
///
|
||||
/// ready!(self.poll_evented.poll_read_ready(cx, ready))?;
|
||||
///
|
||||
/// match self.poll_evented.get_ref().accept() {
|
||||
/// Ok((socket, _)) => Poll::Ready(Ok(socket)),
|
||||
/// Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
|
||||
/// self.poll_evented.clear_read_ready(cx, ready)?;
|
||||
/// Poll::Pending
|
||||
/// }
|
||||
/// Err(e) => Poll::Ready(Err(e)),
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ## Platform-specific events
|
||||
///
|
||||
/// `PollEvented` also allows receiving platform-specific `mio::Ready` events.
|
||||
/// These events are included as part of the read readiness event stream. The
|
||||
/// write readiness event stream is only for `Ready::writable()` events.
|
||||
///
|
||||
/// [`std::io::Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
|
||||
/// [`std::io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
|
||||
/// [`AsyncRead`]: ../io/trait.AsyncRead.html
|
||||
/// [`AsyncWrite`]: ../io/trait.AsyncWrite.html
|
||||
/// [`mio::Evented`]: https://docs.rs/mio/0.6/mio/trait.Evented.html
|
||||
/// [`Registration`]: struct.Registration.html
|
||||
/// [`TcpListener`]: ../net/struct.TcpListener.html
|
||||
/// [`clear_read_ready`]: #method.clear_read_ready
|
||||
/// [`clear_write_ready`]: #method.clear_write_ready
|
||||
/// [`poll_read_ready`]: #method.poll_read_ready
|
||||
/// [`poll_write_ready`]: #method.poll_write_ready
|
||||
pub struct PollEvented<E: Evented> {
|
||||
io: Option<E>,
|
||||
inner: Inner,
|
||||
cfg_io_driver! {
|
||||
/// Associates an I/O resource that implements the [`std::io::Read`] and/or
|
||||
/// [`std::io::Write`] traits with the reactor that drives it.
|
||||
///
|
||||
/// `PollEvented` uses [`Registration`] internally to take a type that
|
||||
/// implements [`mio::Evented`] as well as [`std::io::Read`] and or
|
||||
/// [`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
|
||||
/// used from within the future's execution model. As such, the
|
||||
/// `PollEvented` type provides [`AsyncRead`] and [`AsyncWrite`]
|
||||
/// 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
|
||||
/// `Sync`), the caller must ensure that there are at most two tasks that
|
||||
/// use a `PollEvented` instance concurrently. One for reading and one for
|
||||
/// writing. While violating this requirement is "safe" from a Rust memory
|
||||
/// model point of view, it will result in unexpected behavior in the form
|
||||
/// of lost notifications and tasks hanging.
|
||||
///
|
||||
/// ## Readiness events
|
||||
///
|
||||
/// Besides just providing [`AsyncRead`] and [`AsyncWrite`] implementations,
|
||||
/// this type also supports access to the underlying readiness event stream.
|
||||
/// While similar in function to what [`Registration`] provides, the
|
||||
/// semantics are a bit different.
|
||||
///
|
||||
/// Two functions are provided to access the readiness events:
|
||||
/// [`poll_read_ready`] and [`poll_write_ready`]. These functions return the
|
||||
/// current readiness state of the `PollEvented` instance. If
|
||||
/// [`poll_read_ready`] indicates read readiness, immediately calling
|
||||
/// [`poll_read_ready`] again will also indicate read readiness.
|
||||
///
|
||||
/// 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
|
||||
/// [`clear_write_ready`]. This clears the readiness state until a new
|
||||
/// readiness event is received.
|
||||
///
|
||||
/// This allows the caller to implement additional functions. For example,
|
||||
/// [`TcpListener`] implements poll_accept by using [`poll_read_ready`] and
|
||||
/// [`clear_read_ready`].
|
||||
///
|
||||
/// ```rust
|
||||
/// use tokio::io::PollEvented;
|
||||
///
|
||||
/// use futures::ready;
|
||||
/// use mio::Ready;
|
||||
/// use mio::net::{TcpStream, TcpListener};
|
||||
/// use std::io;
|
||||
/// use std::task::{Context, Poll};
|
||||
///
|
||||
/// struct MyListener {
|
||||
/// poll_evented: PollEvented<TcpListener>,
|
||||
/// }
|
||||
///
|
||||
/// impl MyListener {
|
||||
/// pub fn poll_accept(&mut self, cx: &mut Context<'_>) -> Poll<Result<TcpStream, io::Error>> {
|
||||
/// let ready = Ready::readable();
|
||||
///
|
||||
/// ready!(self.poll_evented.poll_read_ready(cx, ready))?;
|
||||
///
|
||||
/// match self.poll_evented.get_ref().accept() {
|
||||
/// Ok((socket, _)) => Poll::Ready(Ok(socket)),
|
||||
/// Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
|
||||
/// self.poll_evented.clear_read_ready(cx, ready)?;
|
||||
/// Poll::Pending
|
||||
/// }
|
||||
/// Err(e) => Poll::Ready(Err(e)),
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ## Platform-specific events
|
||||
///
|
||||
/// `PollEvented` also allows receiving platform-specific `mio::Ready` events.
|
||||
/// These events are included as part of the read readiness event stream. The
|
||||
/// write readiness event stream is only for `Ready::writable()` events.
|
||||
///
|
||||
/// [`std::io::Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
|
||||
/// [`std::io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
|
||||
/// [`AsyncRead`]: ../io/trait.AsyncRead.html
|
||||
/// [`AsyncWrite`]: ../io/trait.AsyncWrite.html
|
||||
/// [`mio::Evented`]: https://docs.rs/mio/0.6/mio/trait.Evented.html
|
||||
/// [`Registration`]: struct.Registration.html
|
||||
/// [`TcpListener`]: ../net/struct.TcpListener.html
|
||||
/// [`clear_read_ready`]: #method.clear_read_ready
|
||||
/// [`clear_write_ready`]: #method.clear_write_ready
|
||||
/// [`poll_read_ready`]: #method.poll_read_ready
|
||||
/// [`poll_write_ready`]: #method.poll_write_ready
|
||||
pub struct PollEvented<E: Evented> {
|
||||
io: Option<E>,
|
||||
inner: Inner,
|
||||
}
|
||||
}
|
||||
|
||||
struct Inner {
|
||||
|
||||
@@ -5,40 +5,43 @@ use mio::{self, Evented};
|
||||
use std::task::{Context, Poll};
|
||||
use std::io;
|
||||
|
||||
/// Associates an I/O resource with the reactor instance that drives it.
|
||||
///
|
||||
/// A registration represents an I/O resource registered with a Reactor such
|
||||
/// that it will receive task notifications on readiness. This is the lowest
|
||||
/// level API for integrating with a reactor.
|
||||
///
|
||||
/// The association between an I/O resource is made by calling [`new`]. Once
|
||||
/// the association is established, it remains established until the
|
||||
/// registration instance is dropped.
|
||||
///
|
||||
/// A registration instance represents two separate readiness streams. One for
|
||||
/// the read readiness and one for write readiness. These streams are
|
||||
/// independent and can be consumed from separate tasks.
|
||||
///
|
||||
/// **Note**: while `Registration` is `Sync`, the caller must ensure that there
|
||||
/// are at most two tasks that use a registration instance concurrently. One
|
||||
/// task for [`poll_read_ready`] and one task for [`poll_write_ready`]. While
|
||||
/// violating this requirement is "safe" from a Rust memory safety point of
|
||||
/// view, it will result in unexpected behavior in the form of lost
|
||||
/// notifications and tasks hanging.
|
||||
///
|
||||
/// ## Platform-specific events
|
||||
///
|
||||
/// `Registration` also allows receiving platform-specific `mio::Ready` events.
|
||||
/// These events are included as part of the read readiness event stream. The
|
||||
/// write readiness event stream is only for `Ready::writable()` events.
|
||||
///
|
||||
/// [`new`]: #method.new
|
||||
/// [`poll_read_ready`]: #method.poll_read_ready`]
|
||||
/// [`poll_write_ready`]: #method.poll_write_ready`]
|
||||
#[derive(Debug)]
|
||||
pub struct Registration {
|
||||
handle: Handle,
|
||||
address: Address,
|
||||
cfg_io_driver! {
|
||||
/// Associates an I/O resource with the reactor instance that drives it.
|
||||
///
|
||||
/// A registration represents an I/O resource registered with a Reactor such
|
||||
/// that it will receive task notifications on readiness. This is the lowest
|
||||
/// level API for integrating with a reactor.
|
||||
///
|
||||
/// The association between an I/O resource is made by calling [`new`]. Once
|
||||
/// the association is established, it remains established until the
|
||||
/// registration instance is dropped.
|
||||
///
|
||||
/// A registration instance represents two separate readiness streams. One
|
||||
/// for the read readiness and one for write readiness. These streams are
|
||||
/// independent and can be consumed from separate tasks.
|
||||
///
|
||||
/// **Note**: while `Registration` is `Sync`, the caller must ensure that
|
||||
/// there are at most two tasks that use a registration instance
|
||||
/// concurrently. One task for [`poll_read_ready`] and one task for
|
||||
/// [`poll_write_ready`]. While violating this requirement is "safe" from a
|
||||
/// Rust memory safety point of view, it will result in unexpected behavior
|
||||
/// in the form of lost notifications and tasks hanging.
|
||||
///
|
||||
/// ## Platform-specific events
|
||||
///
|
||||
/// `Registration` also allows receiving platform-specific `mio::Ready`
|
||||
/// events. These events are included as part of the read readiness event
|
||||
/// stream. The write readiness event stream is only for `Ready::writable()`
|
||||
/// events.
|
||||
///
|
||||
/// [`new`]: #method.new
|
||||
/// [`poll_read_ready`]: #method.poll_read_ready`]
|
||||
/// [`poll_write_ready`]: #method.poll_write_ready`]
|
||||
#[derive(Debug)]
|
||||
pub struct Registration {
|
||||
handle: Handle,
|
||||
address: Address,
|
||||
}
|
||||
}
|
||||
|
||||
// ===== impl Registration =====
|
||||
|
||||
+32
-30
@@ -16,14 +16,39 @@ use std::sync::atomic::Ordering::{Acquire, Release};
|
||||
use std::sync::Arc;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
/// The readable half of a value returned from `split`.
|
||||
pub struct ReadHalf<T> {
|
||||
inner: Arc<Inner<T>>,
|
||||
}
|
||||
cfg_io_util! {
|
||||
/// The readable half of a value returned from `split`.
|
||||
pub struct ReadHalf<T> {
|
||||
inner: Arc<Inner<T>>,
|
||||
}
|
||||
|
||||
/// The writable half of a value returned from `split`.
|
||||
pub struct WriteHalf<T> {
|
||||
inner: Arc<Inner<T>>,
|
||||
/// The writable half of a value returned from `split`.
|
||||
pub struct WriteHalf<T> {
|
||||
inner: Arc<Inner<T>>,
|
||||
}
|
||||
|
||||
/// Split a single value implementing `AsyncRead + AsyncWrite` into separate
|
||||
/// `AsyncRead` and `AsyncWrite` handles.
|
||||
///
|
||||
/// To restore this read/write object from its `split::ReadHalf` and
|
||||
/// `split::WriteHalf` use `unsplit`.
|
||||
pub fn split<T>(stream: T) -> (ReadHalf<T>, WriteHalf<T>)
|
||||
where
|
||||
T: AsyncRead + AsyncWrite,
|
||||
{
|
||||
let inner = Arc::new(Inner {
|
||||
locked: AtomicBool::new(false),
|
||||
stream: UnsafeCell::new(stream),
|
||||
});
|
||||
|
||||
let rd = ReadHalf {
|
||||
inner: inner.clone(),
|
||||
};
|
||||
|
||||
let wr = WriteHalf { inner };
|
||||
|
||||
(rd, wr)
|
||||
}
|
||||
}
|
||||
|
||||
struct Inner<T> {
|
||||
@@ -35,29 +60,6 @@ struct Guard<'a, T> {
|
||||
inner: &'a Inner<T>,
|
||||
}
|
||||
|
||||
/// Split a single value implementing `AsyncRead + AsyncWrite` into separate
|
||||
/// `AsyncRead` and `AsyncWrite` handles.
|
||||
///
|
||||
/// To restore this read/write object from its `split::ReadHalf` and
|
||||
/// `split::WriteHalf` use `unsplit`.
|
||||
pub fn split<T>(stream: T) -> (ReadHalf<T>, WriteHalf<T>)
|
||||
where
|
||||
T: AsyncRead + AsyncWrite,
|
||||
{
|
||||
let inner = Arc::new(Inner {
|
||||
locked: AtomicBool::new(false),
|
||||
stream: UnsafeCell::new(stream),
|
||||
});
|
||||
|
||||
let rd = ReadHalf {
|
||||
inner: inner.clone(),
|
||||
};
|
||||
|
||||
let wr = WriteHalf { inner };
|
||||
|
||||
(rd, wr)
|
||||
}
|
||||
|
||||
impl<T> ReadHalf<T> {
|
||||
/// Reunite with a previously split `WriteHalf`.
|
||||
///
|
||||
|
||||
+23
-21
@@ -6,28 +6,30 @@ use std::pin::Pin;
|
||||
use std::task::Context;
|
||||
use std::task::Poll;
|
||||
|
||||
/// A handle to the standard error stream of a process.
|
||||
///
|
||||
/// The handle implements the [`AsyncWrite`] trait, but beware that concurrent
|
||||
/// writes to `Stderr` must be executed with care.
|
||||
///
|
||||
/// Created by the [`stderr`] function.
|
||||
///
|
||||
/// [`stderr`]: fn.stderr.html
|
||||
/// [`AsyncWrite`]: trait.AsyncWrite.html
|
||||
#[derive(Debug)]
|
||||
pub struct Stderr {
|
||||
std: Blocking<std::io::Stderr>,
|
||||
}
|
||||
cfg_io_std! {
|
||||
/// A handle to the standard error stream of a process.
|
||||
///
|
||||
/// The handle implements the [`AsyncWrite`] trait, but beware that concurrent
|
||||
/// writes to `Stderr` must be executed with care.
|
||||
///
|
||||
/// Created by the [`stderr`] function.
|
||||
///
|
||||
/// [`stderr`]: fn.stderr.html
|
||||
/// [`AsyncWrite`]: trait.AsyncWrite.html
|
||||
#[derive(Debug)]
|
||||
pub struct Stderr {
|
||||
std: Blocking<std::io::Stderr>,
|
||||
}
|
||||
|
||||
/// Constructs a new handle to the standard error of the current process.
|
||||
///
|
||||
/// The returned handle allows writing to standard error from the within the
|
||||
/// Tokio runtime.
|
||||
pub fn stderr() -> Stderr {
|
||||
let std = io::stderr();
|
||||
Stderr {
|
||||
std: Blocking::new(std),
|
||||
/// Constructs a new handle to the standard error of the current process.
|
||||
///
|
||||
/// The returned handle allows writing to standard error from the within the
|
||||
/// Tokio runtime.
|
||||
pub fn stderr() -> Stderr {
|
||||
let std = io::stderr();
|
||||
Stderr {
|
||||
std: Blocking::new(std),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+29
-27
@@ -6,34 +6,36 @@ use std::pin::Pin;
|
||||
use std::task::Context;
|
||||
use std::task::Poll;
|
||||
|
||||
/// A handle to the standard input stream of a process.
|
||||
///
|
||||
/// The handle implements the [`AsyncRead`] trait, but beware that concurrent
|
||||
/// reads of `Stdin` must be executed with care.
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// Created by the [`stdin`] function.
|
||||
///
|
||||
/// [`stdin`]: fn.stdin.html
|
||||
/// [`AsyncRead`]: trait.AsyncRead.html
|
||||
#[derive(Debug)]
|
||||
pub struct Stdin {
|
||||
std: Blocking<std::io::Stdin>,
|
||||
}
|
||||
cfg_io_std! {
|
||||
/// A handle to the standard input stream of a process.
|
||||
///
|
||||
/// The handle implements the [`AsyncRead`] trait, but beware that concurrent
|
||||
/// reads of `Stdin` must be executed with care.
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// Created by the [`stdin`] function.
|
||||
///
|
||||
/// [`stdin`]: fn.stdin.html
|
||||
/// [`AsyncRead`]: trait.AsyncRead.html
|
||||
#[derive(Debug)]
|
||||
pub struct Stdin {
|
||||
std: Blocking<std::io::Stdin>,
|
||||
}
|
||||
|
||||
/// Constructs a new handle to the standard input of the current process.
|
||||
///
|
||||
/// The returned handle allows reading from standard input from the within the
|
||||
/// Tokio runtime.
|
||||
pub fn stdin() -> Stdin {
|
||||
let std = io::stdin();
|
||||
Stdin {
|
||||
std: Blocking::new(std),
|
||||
/// Constructs a new handle to the standard input of the current process.
|
||||
///
|
||||
/// The returned handle allows reading from standard input from the within the
|
||||
/// Tokio runtime.
|
||||
pub fn stdin() -> Stdin {
|
||||
let std = io::stdin();
|
||||
Stdin {
|
||||
std: Blocking::new(std),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+23
-21
@@ -6,28 +6,30 @@ use std::pin::Pin;
|
||||
use std::task::Context;
|
||||
use std::task::Poll;
|
||||
|
||||
/// A handle to the standard output stream of a process.
|
||||
///
|
||||
/// The handle implements the [`AsyncWrite`] trait, but beware that concurrent
|
||||
/// writes to `Stdout` must be executed with care.
|
||||
///
|
||||
/// Created by the [`stdout`] function.
|
||||
///
|
||||
/// [`stdout`]: fn.stdout.html
|
||||
/// [`AsyncWrite`]: trait.AsyncWrite.html
|
||||
#[derive(Debug)]
|
||||
pub struct Stdout {
|
||||
std: Blocking<std::io::Stdout>,
|
||||
}
|
||||
cfg_io_std! {
|
||||
/// A handle to the standard output stream of a process.
|
||||
///
|
||||
/// The handle implements the [`AsyncWrite`] trait, but beware that concurrent
|
||||
/// writes to `Stdout` must be executed with care.
|
||||
///
|
||||
/// Created by the [`stdout`] function.
|
||||
///
|
||||
/// [`stdout`]: fn.stdout.html
|
||||
/// [`AsyncWrite`]: trait.AsyncWrite.html
|
||||
#[derive(Debug)]
|
||||
pub struct Stdout {
|
||||
std: Blocking<std::io::Stdout>,
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// runtime.
|
||||
pub fn stdout() -> Stdout {
|
||||
let std = io::stdout();
|
||||
Stdout {
|
||||
std: Blocking::new(std),
|
||||
/// 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
|
||||
/// runtime.
|
||||
pub fn stdout() -> Stdout {
|
||||
let std = io::stdout();
|
||||
Stdout {
|
||||
std: Blocking::new(std),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,118 +4,120 @@ use crate::io::util::read_until::{read_until, ReadUntil};
|
||||
use crate::io::util::split::{split, Split};
|
||||
use crate::io::AsyncBufRead;
|
||||
|
||||
/// An extension trait which adds utility methods to `AsyncBufRead` types.
|
||||
pub trait AsyncBufReadExt: AsyncBufRead {
|
||||
/// Creates a future which will read all the bytes associated with this I/O
|
||||
/// object into `buf` until the delimiter `byte` or EOF is reached.
|
||||
/// This method is the async equivalent to [`BufRead::read_until`](std::io::BufRead::read_until).
|
||||
///
|
||||
/// This function will read bytes from the underlying stream until the
|
||||
/// delimiter or EOF is found. Once found, all bytes up to, and including,
|
||||
/// the delimiter (if found) will be appended to `buf`.
|
||||
///
|
||||
/// The returned future will resolve to the number of bytes read once the read
|
||||
/// operation is completed.
|
||||
///
|
||||
/// In the case of an error the buffer and the object will be discarded, with
|
||||
/// the error yielded.
|
||||
fn read_until<'a>(&'a mut self, byte: u8, buf: &'a mut Vec<u8>) -> ReadUntil<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
read_until(self, byte, buf)
|
||||
}
|
||||
cfg_io_util! {
|
||||
/// An extension trait which adds utility methods to `AsyncBufRead` types.
|
||||
pub trait AsyncBufReadExt: AsyncBufRead {
|
||||
/// Creates a future which will read all the bytes associated with this I/O
|
||||
/// object into `buf` until the delimiter `byte` or EOF is reached.
|
||||
/// This method is the async equivalent to [`BufRead::read_until`](std::io::BufRead::read_until).
|
||||
///
|
||||
/// This function will read bytes from the underlying stream until the
|
||||
/// delimiter or EOF is found. Once found, all bytes up to, and including,
|
||||
/// the delimiter (if found) will be appended to `buf`.
|
||||
///
|
||||
/// The returned future will resolve to the number of bytes read once the read
|
||||
/// operation is completed.
|
||||
///
|
||||
/// In the case of an error the buffer and the object will be discarded, with
|
||||
/// the error yielded.
|
||||
fn read_until<'a>(&'a mut self, byte: u8, buf: &'a mut Vec<u8>) -> ReadUntil<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
read_until(self, byte, buf)
|
||||
}
|
||||
|
||||
/// Creates a future which will read all the bytes associated with this I/O
|
||||
/// object into `buf` until a newline (the 0xA byte) or EOF is reached,
|
||||
/// This method is the async equivalent to [`BufRead::read_line`](std::io::BufRead::read_line).
|
||||
///
|
||||
/// This function will read bytes from the underlying stream until the
|
||||
/// newline delimiter (the 0xA byte) or EOF is found. Once found, all bytes
|
||||
/// up to, and including, the delimiter (if found) will be appended to
|
||||
/// `buf`.
|
||||
///
|
||||
/// The returned future will resolve to the number of bytes read once the read
|
||||
/// operation is completed.
|
||||
///
|
||||
/// In the case of an error the buffer and the object will be discarded, with
|
||||
/// the error yielded.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This function has the same error semantics as [`read_until`] and will
|
||||
/// also return an error if the read bytes are not valid UTF-8. If an I/O
|
||||
/// error is encountered then `buf` may contain some bytes already read in
|
||||
/// the event that all data read so far was valid UTF-8.
|
||||
///
|
||||
/// [`read_until`]: AsyncBufReadExt::read_until
|
||||
fn read_line<'a>(&'a mut self, buf: &'a mut String) -> ReadLine<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
read_line(self, buf)
|
||||
}
|
||||
/// Creates a future which will read all the bytes associated with this I/O
|
||||
/// object into `buf` until a newline (the 0xA byte) or EOF is reached,
|
||||
/// This method is the async equivalent to [`BufRead::read_line`](std::io::BufRead::read_line).
|
||||
///
|
||||
/// This function will read bytes from the underlying stream until the
|
||||
/// newline delimiter (the 0xA byte) or EOF is found. Once found, all bytes
|
||||
/// up to, and including, the delimiter (if found) will be appended to
|
||||
/// `buf`.
|
||||
///
|
||||
/// The returned future will resolve to the number of bytes read once the read
|
||||
/// operation is completed.
|
||||
///
|
||||
/// In the case of an error the buffer and the object will be discarded, with
|
||||
/// the error yielded.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This function has the same error semantics as [`read_until`] and will
|
||||
/// also return an error if the read bytes are not valid UTF-8. If an I/O
|
||||
/// error is encountered then `buf` may contain some bytes already read in
|
||||
/// the event that all data read so far was valid UTF-8.
|
||||
///
|
||||
/// [`read_until`]: AsyncBufReadExt::read_until
|
||||
fn read_line<'a>(&'a mut self, buf: &'a mut String) -> ReadLine<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
read_line(self, buf)
|
||||
}
|
||||
|
||||
/// Returns a stream of the contents of this reader split on the byte
|
||||
/// `byte`.
|
||||
///
|
||||
/// This method is the asynchronous equivalent to
|
||||
/// [`BufRead::split`](std::io::BufRead::split).
|
||||
///
|
||||
/// The stream returned from this function will yield instances of
|
||||
/// [`io::Result`]`<`[`Vec<u8>`]`>`. Each vector returned will *not* have
|
||||
/// the delimiter byte at the end.
|
||||
///
|
||||
/// [`io::Result`]: std::io::Result
|
||||
/// [`Vec<u8>`]: std::vec::Vec
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Each item of the stream has the same error semantics as
|
||||
/// [`AsyncBufReadExt::read_until`](AsyncBufReadExt::read_until).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use tokio::io::AsyncBufRead;
|
||||
/// use tokio::io::AsyncBufReadExt;
|
||||
///
|
||||
/// # async fn dox(my_buf_read: impl AsyncBufRead + Unpin) -> std::io::Result<()> {
|
||||
/// let mut segments = my_buf_read.split(b'f');
|
||||
///
|
||||
/// while let Some(segment) = segments.next_segment().await? {
|
||||
/// println!("length = {}", segment.len())
|
||||
/// }
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
fn split(self, byte: u8) -> Split<Self>
|
||||
where
|
||||
Self: Sized + Unpin,
|
||||
{
|
||||
split(self, byte)
|
||||
}
|
||||
/// Returns a stream of the contents of this reader split on the byte
|
||||
/// `byte`.
|
||||
///
|
||||
/// This method is the asynchronous equivalent to
|
||||
/// [`BufRead::split`](std::io::BufRead::split).
|
||||
///
|
||||
/// The stream returned from this function will yield instances of
|
||||
/// [`io::Result`]`<`[`Vec<u8>`]`>`. Each vector returned will *not* have
|
||||
/// the delimiter byte at the end.
|
||||
///
|
||||
/// [`io::Result`]: std::io::Result
|
||||
/// [`Vec<u8>`]: std::vec::Vec
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Each item of the stream has the same error semantics as
|
||||
/// [`AsyncBufReadExt::read_until`](AsyncBufReadExt::read_until).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use tokio::io::AsyncBufRead;
|
||||
/// use tokio::io::AsyncBufReadExt;
|
||||
///
|
||||
/// # async fn dox(my_buf_read: impl AsyncBufRead + Unpin) -> std::io::Result<()> {
|
||||
/// let mut segments = my_buf_read.split(b'f');
|
||||
///
|
||||
/// while let Some(segment) = segments.next_segment().await? {
|
||||
/// println!("length = {}", segment.len())
|
||||
/// }
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
fn split(self, byte: u8) -> Split<Self>
|
||||
where
|
||||
Self: Sized + Unpin,
|
||||
{
|
||||
split(self, byte)
|
||||
}
|
||||
|
||||
/// Returns a stream over the lines of this reader.
|
||||
/// This method is the async equivalent to [`BufRead::lines`](std::io::BufRead::lines).
|
||||
///
|
||||
/// The stream returned from this function will yield instances of
|
||||
/// [`io::Result`]`<`[`String`]`>`. Each string returned will *not* have a newline
|
||||
/// byte (the 0xA byte) or CRLF (0xD, 0xA bytes) at the end.
|
||||
///
|
||||
/// [`io::Result`]: std::io::Result
|
||||
/// [`String`]: String
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Each line of the stream has the same error semantics as [`AsyncBufReadExt::read_line`].
|
||||
///
|
||||
/// [`AsyncBufReadExt::read_line`]: AsyncBufReadExt::read_line
|
||||
fn lines(self) -> Lines<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
lines(self)
|
||||
/// Returns a stream over the lines of this reader.
|
||||
/// This method is the async equivalent to [`BufRead::lines`](std::io::BufRead::lines).
|
||||
///
|
||||
/// The stream returned from this function will yield instances of
|
||||
/// [`io::Result`]`<`[`String`]`>`. Each string returned will *not* have a newline
|
||||
/// byte (the 0xA byte) or CRLF (0xD, 0xA bytes) at the end.
|
||||
///
|
||||
/// [`io::Result`]: std::io::Result
|
||||
/// [`String`]: String
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Each line of the stream has the same error semantics as [`AsyncBufReadExt::read_line`].
|
||||
///
|
||||
/// [`AsyncBufReadExt::read_line`]: AsyncBufReadExt::read_line
|
||||
fn lines(self) -> Lines<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
lines(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,85 +7,87 @@ use crate::io::util::read_to_string::{read_to_string, ReadToString};
|
||||
use crate::io::util::take::{take, Take};
|
||||
use crate::io::{AsyncRead, AsyncWrite};
|
||||
|
||||
/// An extension trait which adds utility methods to `AsyncRead` types.
|
||||
pub trait AsyncReadExt: AsyncRead {
|
||||
/// Creates an adaptor which will chain this stream with another.
|
||||
///
|
||||
/// The returned `AsyncRead` instance will first read all bytes from this object
|
||||
/// until EOF is encountered. Afterwards the output is equivalent to the
|
||||
/// output of `next`.
|
||||
fn chain<R>(self, next: R) -> Chain<Self, R>
|
||||
where
|
||||
Self: Sized,
|
||||
R: AsyncRead,
|
||||
{
|
||||
chain(self, next)
|
||||
}
|
||||
cfg_io_util! {
|
||||
/// An extension trait which adds utility methods to `AsyncRead` types.
|
||||
pub trait AsyncReadExt: AsyncRead {
|
||||
/// Creates an adaptor which will chain this stream with another.
|
||||
///
|
||||
/// The returned `AsyncRead` instance will first read all bytes from this object
|
||||
/// until EOF is encountered. Afterwards the output is equivalent to the
|
||||
/// output of `next`.
|
||||
fn chain<R>(self, next: R) -> Chain<Self, R>
|
||||
where
|
||||
Self: Sized,
|
||||
R: AsyncRead,
|
||||
{
|
||||
chain(self, next)
|
||||
}
|
||||
|
||||
/// Copy all data from `self` into the provided `AsyncWrite`.
|
||||
///
|
||||
/// The returned future will copy all the bytes read from `reader` into the
|
||||
/// `writer` specified. This future will only complete once the `reader`
|
||||
/// has hit EOF and all bytes have been written to and flushed from the
|
||||
/// `writer` provided.
|
||||
///
|
||||
/// On success the number of bytes is returned and the `reader` and `writer`
|
||||
/// are consumed. On error the error is returned and the I/O objects are
|
||||
/// consumed as well.
|
||||
fn copy<'a, W>(&'a mut self, dst: &'a mut W) -> Copy<'a, Self, W>
|
||||
where
|
||||
Self: Unpin,
|
||||
W: AsyncWrite + Unpin + ?Sized,
|
||||
{
|
||||
copy(self, dst)
|
||||
}
|
||||
/// Copy all data from `self` into the provided `AsyncWrite`.
|
||||
///
|
||||
/// The returned future will copy all the bytes read from `reader` into the
|
||||
/// `writer` specified. This future will only complete once the `reader`
|
||||
/// has hit EOF and all bytes have been written to and flushed from the
|
||||
/// `writer` provided.
|
||||
///
|
||||
/// On success the number of bytes is returned and the `reader` and `writer`
|
||||
/// are consumed. On error the error is returned and the I/O objects are
|
||||
/// consumed as well.
|
||||
fn copy<'a, W>(&'a mut self, dst: &'a mut W) -> Copy<'a, Self, W>
|
||||
where
|
||||
Self: Unpin,
|
||||
W: AsyncWrite + Unpin + ?Sized,
|
||||
{
|
||||
copy(self, dst)
|
||||
}
|
||||
|
||||
/// Read data into the provided buffer.
|
||||
///
|
||||
/// The returned future will resolve to the number of bytes read once the
|
||||
/// read operation is completed.
|
||||
fn read<'a>(&'a mut self, dst: &'a mut [u8]) -> Read<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
read(self, dst)
|
||||
}
|
||||
/// Read data into the provided buffer.
|
||||
///
|
||||
/// The returned future will resolve to the number of bytes read once the
|
||||
/// read operation is completed.
|
||||
fn read<'a>(&'a mut self, dst: &'a mut [u8]) -> Read<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
read(self, dst)
|
||||
}
|
||||
|
||||
/// Read exactly the amount of data needed to fill the provided buffer.
|
||||
fn read_exact<'a>(&'a mut self, dst: &'a mut [u8]) -> ReadExact<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
read_exact(self, dst)
|
||||
}
|
||||
/// Read exactly the amount of data needed to fill the provided buffer.
|
||||
fn read_exact<'a>(&'a mut self, dst: &'a mut [u8]) -> ReadExact<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
read_exact(self, dst)
|
||||
}
|
||||
|
||||
/// Read all bytes until EOF in this source, placing them into `dst`.
|
||||
///
|
||||
/// On success the total number of bytes read is returned.
|
||||
fn read_to_end<'a>(&'a mut self, dst: &'a mut Vec<u8>) -> ReadToEnd<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
read_to_end(self, dst)
|
||||
}
|
||||
/// Read all bytes until EOF in this source, placing them into `dst`.
|
||||
///
|
||||
/// On success the total number of bytes read is returned.
|
||||
fn read_to_end<'a>(&'a mut self, dst: &'a mut Vec<u8>) -> ReadToEnd<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
read_to_end(self, dst)
|
||||
}
|
||||
|
||||
/// Read all bytes until EOF in this source, placing them into `dst`.
|
||||
///
|
||||
/// On success the total number of bytes read is returned.
|
||||
fn read_to_string<'a>(&'a mut self, dst: &'a mut String) -> ReadToString<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
read_to_string(self, dst)
|
||||
}
|
||||
/// Read all bytes until EOF in this source, placing them into `dst`.
|
||||
///
|
||||
/// On success the total number of bytes read is returned.
|
||||
fn read_to_string<'a>(&'a mut self, dst: &'a mut String) -> ReadToString<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
read_to_string(self, dst)
|
||||
}
|
||||
|
||||
/// Creates an AsyncRead adapter which will read at most `limit` bytes
|
||||
/// from the underlying reader.
|
||||
fn take(self, limit: u64) -> Take<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
take(self, limit)
|
||||
/// Creates an AsyncRead adapter which will read at most `limit` bytes
|
||||
/// from the underlying reader.
|
||||
fn take(self, limit: u64) -> Take<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
take(self, limit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,38 +4,40 @@ use crate::io::util::write::{write, Write};
|
||||
use crate::io::util::write_all::{write_all, WriteAll};
|
||||
use crate::io::AsyncWrite;
|
||||
|
||||
/// An extension trait which adds utility methods to `AsyncWrite` types.
|
||||
pub trait AsyncWriteExt: AsyncWrite {
|
||||
/// Write a buffer into this writter, returning how many bytes were written.
|
||||
fn write<'a>(&'a mut self, src: &'a [u8]) -> Write<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
write(self, src)
|
||||
}
|
||||
cfg_io_util! {
|
||||
/// An extension trait which adds utility methods to `AsyncWrite` types.
|
||||
pub trait AsyncWriteExt: AsyncWrite {
|
||||
/// Write a buffer into this writter, returning how many bytes were written.
|
||||
fn write<'a>(&'a mut self, src: &'a [u8]) -> Write<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
write(self, src)
|
||||
}
|
||||
|
||||
/// Attempt to write an entire buffer into this writter.
|
||||
fn write_all<'a>(&'a mut self, src: &'a [u8]) -> WriteAll<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
write_all(self, src)
|
||||
}
|
||||
/// Attempt to write an entire buffer into this writter.
|
||||
fn write_all<'a>(&'a mut self, src: &'a [u8]) -> WriteAll<'a, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
write_all(self, src)
|
||||
}
|
||||
|
||||
/// Flush the contents of this writer.
|
||||
fn flush(&mut self) -> Flush<'_, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
flush(self)
|
||||
}
|
||||
/// Flush the contents of this writer.
|
||||
fn flush(&mut self) -> Flush<'_, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
flush(self)
|
||||
}
|
||||
|
||||
/// Shutdown this writer.
|
||||
fn shutdown(&mut self) -> Shutdown<'_, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
shutdown(self)
|
||||
/// Shutdown this writer.
|
||||
fn shutdown(&mut self) -> Shutdown<'_, Self>
|
||||
where
|
||||
Self: Unpin,
|
||||
{
|
||||
shutdown(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ pin_project! {
|
||||
/// When the `BufReader` is dropped, the contents of its buffer will be
|
||||
/// discarded. Creating multiple instances of a `BufReader` on the same
|
||||
/// stream can cause data loss.
|
||||
// TODO: Examples
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
|
||||
pub struct BufReader<R> {
|
||||
#[pin]
|
||||
pub(super) inner: R,
|
||||
|
||||
@@ -16,6 +16,7 @@ pin_project! {
|
||||
/// 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.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
|
||||
pub struct BufStream<RW> {
|
||||
#[pin]
|
||||
inner: BufReader<BufWriter<RW>>,
|
||||
|
||||
@@ -29,7 +29,7 @@ pin_project! {
|
||||
/// [`AsyncWrite`]: AsyncWrite
|
||||
/// [`flush`]: super::AsyncWriteExt::flush
|
||||
///
|
||||
// TODO: Examples
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
|
||||
pub struct BufWriter<W> {
|
||||
#[pin]
|
||||
pub(super) inner: W,
|
||||
|
||||
@@ -9,6 +9,7 @@ use std::task::{Context, Poll};
|
||||
pin_project! {
|
||||
/// Stream for the [`chain`](super::AsyncReadExt::chain) method.
|
||||
#[must_use = "streams do nothing unless polled"]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
|
||||
pub struct Chain<T, U> {
|
||||
#[pin]
|
||||
first: T,
|
||||
|
||||
+66
-64
@@ -5,71 +5,73 @@ use std::io;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
/// A future that asynchronously copies the entire contents of a reader into a
|
||||
/// writer.
|
||||
///
|
||||
/// This struct is generally created by calling [`copy`][copy]. Please
|
||||
/// see the documentation of `copy()` for more details.
|
||||
///
|
||||
/// [copy]: fn.copy.html
|
||||
#[derive(Debug)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct Copy<'a, R: ?Sized, W: ?Sized> {
|
||||
reader: &'a mut R,
|
||||
read_done: bool,
|
||||
writer: &'a mut W,
|
||||
pos: usize,
|
||||
cap: usize,
|
||||
amt: u64,
|
||||
buf: Box<[u8]>,
|
||||
}
|
||||
cfg_io_util! {
|
||||
/// A future that asynchronously copies the entire contents of a reader into a
|
||||
/// writer.
|
||||
///
|
||||
/// This struct is generally created by calling [`copy`][copy]. Please
|
||||
/// see the documentation of `copy()` for more details.
|
||||
///
|
||||
/// [copy]: fn.copy.html
|
||||
#[derive(Debug)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct Copy<'a, R: ?Sized, W: ?Sized> {
|
||||
reader: &'a mut R,
|
||||
read_done: bool,
|
||||
writer: &'a mut W,
|
||||
pos: usize,
|
||||
cap: usize,
|
||||
amt: u64,
|
||||
buf: Box<[u8]>,
|
||||
}
|
||||
|
||||
/// Asynchronously copies the entire contents of a reader into a writer.
|
||||
///
|
||||
/// This function returns a future that will continuously read data from
|
||||
/// `reader` and then write it into `writer` in a streaming fashion until
|
||||
/// `reader` returns EOF.
|
||||
///
|
||||
/// On success, the total number of bytes that were copied from
|
||||
/// `reader` to `writer` is returned.
|
||||
///
|
||||
/// This is an asynchronous version of [`std::io::copy`][std].
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// The returned future will finish with an error will return an error
|
||||
/// immediately if any call to `poll_read` or `poll_write` returns an error.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use tokio::io;
|
||||
///
|
||||
/// # async fn dox() -> std::io::Result<()> {
|
||||
/// let mut reader: &[u8] = b"hello";
|
||||
/// let mut writer: Vec<u8> = vec![];
|
||||
///
|
||||
/// io::copy(&mut reader, &mut writer).await?;
|
||||
///
|
||||
/// assert_eq!(&b"hello"[..], &writer[..]);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [std]: https://doc.rust-lang.org/std/io/fn.copy.html
|
||||
pub fn copy<'a, R, W>(reader: &'a mut R, writer: &'a mut W) -> Copy<'a, R, W>
|
||||
where
|
||||
R: AsyncRead + Unpin + ?Sized,
|
||||
W: AsyncWrite + Unpin + ?Sized,
|
||||
{
|
||||
Copy {
|
||||
reader,
|
||||
read_done: false,
|
||||
writer,
|
||||
amt: 0,
|
||||
pos: 0,
|
||||
cap: 0,
|
||||
buf: Box::new([0; 2048]),
|
||||
/// Asynchronously copies the entire contents of a reader into a writer.
|
||||
///
|
||||
/// This function returns a future that will continuously read data from
|
||||
/// `reader` and then write it into `writer` in a streaming fashion until
|
||||
/// `reader` returns EOF.
|
||||
///
|
||||
/// On success, the total number of bytes that were copied from `reader` to
|
||||
/// `writer` is returned.
|
||||
///
|
||||
/// This is an asynchronous version of [`std::io::copy`][std].
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// The returned future will finish with an error will return an error
|
||||
/// immediately if any call to `poll_read` or `poll_write` returns an error.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use tokio::io;
|
||||
///
|
||||
/// # async fn dox() -> std::io::Result<()> {
|
||||
/// let mut reader: &[u8] = b"hello";
|
||||
/// let mut writer: Vec<u8> = vec![];
|
||||
///
|
||||
/// io::copy(&mut reader, &mut writer).await?;
|
||||
///
|
||||
/// assert_eq!(&b"hello"[..], &writer[..]);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [std]: https://doc.rust-lang.org/std/io/fn.copy.html
|
||||
pub fn copy<'a, R, W>(reader: &'a mut R, writer: &'a mut W) -> Copy<'a, R, W>
|
||||
where
|
||||
R: AsyncRead + Unpin + ?Sized,
|
||||
W: AsyncWrite + Unpin + ?Sized,
|
||||
{
|
||||
Copy {
|
||||
reader,
|
||||
read_done: false,
|
||||
writer,
|
||||
amt: 0,
|
||||
pos: 0,
|
||||
cap: 0,
|
||||
buf: Box::new([0; 2048]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+36
-34
@@ -5,41 +5,43 @@ use std::io;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
// An async reader which is always at EOF.
|
||||
///
|
||||
/// This struct is generally created by calling [`empty`]. Please see
|
||||
/// the documentation of [`empty()`][`empty`] for more details.
|
||||
///
|
||||
/// This is an asynchronous version of [`std::io::empty`][std].
|
||||
///
|
||||
/// [`empty`]: fn.empty.html
|
||||
/// [std]: https://doc.rust-lang.org/std/io/struct.Empty.html
|
||||
pub struct Empty {
|
||||
_p: (),
|
||||
}
|
||||
cfg_io_util! {
|
||||
// An async reader which is always at EOF.
|
||||
///
|
||||
/// This struct is generally created by calling [`empty`]. Please see
|
||||
/// the documentation of [`empty()`][`empty`] for more details.
|
||||
///
|
||||
/// This is an asynchronous version of [`std::io::empty`][std].
|
||||
///
|
||||
/// [`empty`]: fn.empty.html
|
||||
/// [std]: https://doc.rust-lang.org/std/io/struct.Empty.html
|
||||
pub struct Empty {
|
||||
_p: (),
|
||||
}
|
||||
|
||||
/// Creates a new empty async reader.
|
||||
///
|
||||
/// All reads from the returned reader will return `Poll::Ready(Ok(0))`.
|
||||
///
|
||||
/// This is an asynchronous version of [`std::io::empty`][std].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// 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());
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [std]: https://doc.rust-lang.org/std/io/fn.empty.html
|
||||
pub fn empty() -> Empty {
|
||||
Empty { _p: () }
|
||||
/// Creates a new empty async reader.
|
||||
///
|
||||
/// All reads from the returned reader will return `Poll::Ready(Ok(0))`.
|
||||
///
|
||||
/// This is an asynchronous version of [`std::io::empty`][std].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// 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());
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [std]: https://doc.rust-lang.org/std/io/fn.empty.html
|
||||
pub fn empty() -> Empty {
|
||||
Empty { _p: () }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncRead for Empty {
|
||||
|
||||
@@ -5,12 +5,14 @@ use std::io;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
/// A future used to fully flush an I/O object.
|
||||
///
|
||||
/// Created by the [`AsyncWriteExt::flush`] function.
|
||||
#[derive(Debug)]
|
||||
pub struct Flush<'a, A: ?Sized> {
|
||||
a: &'a mut A,
|
||||
cfg_io_util! {
|
||||
/// A future used to fully flush an I/O object.
|
||||
///
|
||||
/// Created by the [`AsyncWriteExt::flush`] function.
|
||||
#[derive(Debug)]
|
||||
pub struct Flush<'a, A: ?Sized> {
|
||||
a: &'a mut A,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a future which will entirely flush an I/O object.
|
||||
|
||||
@@ -11,6 +11,7 @@ pin_project! {
|
||||
/// Stream for the [`lines`](crate::io::AsyncBufReadExt::lines) method.
|
||||
#[derive(Debug)]
|
||||
#[must_use = "streams do nothing unless polled"]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
|
||||
pub struct Lines<R> {
|
||||
#[pin]
|
||||
reader: R,
|
||||
|
||||
@@ -18,15 +18,17 @@ where
|
||||
Read { reader, buf }
|
||||
}
|
||||
|
||||
/// A future which can be used to easily read available number of bytes to fill
|
||||
/// a buffer.
|
||||
///
|
||||
/// Created by the [`read`] function.
|
||||
#[derive(Debug)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct Read<'a, R: ?Sized> {
|
||||
reader: &'a mut R,
|
||||
buf: &'a mut [u8],
|
||||
cfg_io_util! {
|
||||
/// A future which can be used to easily read available number of bytes to fill
|
||||
/// a buffer.
|
||||
///
|
||||
/// Created by the [`read`] function.
|
||||
#[derive(Debug)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct Read<'a, R: ?Sized> {
|
||||
reader: &'a mut R,
|
||||
buf: &'a mut [u8],
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> Future for Read<'_, R>
|
||||
|
||||
@@ -21,16 +21,18 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a future which will read exactly enough bytes to fill `buf`,
|
||||
/// returning an error if EOF is hit sooner.
|
||||
///
|
||||
/// On success the number of bytes is returned
|
||||
#[derive(Debug)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct ReadExact<'a, A: ?Sized> {
|
||||
reader: &'a mut A,
|
||||
buf: &'a mut [u8],
|
||||
pos: usize,
|
||||
cfg_io_util! {
|
||||
/// Creates a future which will read exactly enough bytes to fill `buf`,
|
||||
/// returning an error if EOF is hit sooner.
|
||||
///
|
||||
/// On success the number of bytes is returned
|
||||
#[derive(Debug)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct ReadExact<'a, A: ?Sized> {
|
||||
reader: &'a mut A,
|
||||
buf: &'a mut [u8],
|
||||
pos: usize,
|
||||
}
|
||||
}
|
||||
|
||||
fn eof() -> io::Error {
|
||||
|
||||
@@ -8,14 +8,16 @@ use std::pin::Pin;
|
||||
use std::str;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
/// Future for the [`read_line`](crate::io::AsyncBufReadExt::read_line) method.
|
||||
#[derive(Debug)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct ReadLine<'a, R: ?Sized> {
|
||||
reader: &'a mut R,
|
||||
buf: &'a mut String,
|
||||
bytes: Vec<u8>,
|
||||
read: usize,
|
||||
cfg_io_util! {
|
||||
/// Future for the [`read_line`](crate::io::AsyncBufReadExt::read_line) method.
|
||||
#[derive(Debug)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct ReadLine<'a, R: ?Sized> {
|
||||
reader: &'a mut R,
|
||||
buf: &'a mut String,
|
||||
bytes: Vec<u8>,
|
||||
read: usize,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn read_line<'a, R>(reader: &'a mut R, buf: &'a mut String) -> ReadLine<'a, R>
|
||||
|
||||
@@ -8,6 +8,7 @@ use std::task::{Context, Poll};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[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> {
|
||||
reader: &'a mut R,
|
||||
buf: &'a mut Vec<u8>,
|
||||
|
||||
@@ -6,14 +6,16 @@ use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
use std::{io, mem, str};
|
||||
|
||||
/// Future for the [`read_to_string`](super::AsyncReadExt::read_to_string) method.
|
||||
#[derive(Debug)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct ReadToString<'a, R: ?Sized> {
|
||||
reader: &'a mut R,
|
||||
buf: &'a mut String,
|
||||
bytes: Vec<u8>,
|
||||
start_len: usize,
|
||||
cfg_io_util! {
|
||||
/// Future for the [`read_to_string`](super::AsyncReadExt::read_to_string) method.
|
||||
#[derive(Debug)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct ReadToString<'a, R: ?Sized> {
|
||||
reader: &'a mut R,
|
||||
buf: &'a mut String,
|
||||
bytes: Vec<u8>,
|
||||
start_len: usize,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn read_to_string<'a, R>(reader: &'a mut R, buf: &'a mut String) -> ReadToString<'a, R>
|
||||
|
||||
@@ -6,14 +6,16 @@ use std::mem;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
/// Future for the [`read_until`](crate::io::AsyncBufReadExt::read_until) method.
|
||||
#[derive(Debug)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct ReadUntil<'a, R: ?Sized> {
|
||||
reader: &'a mut R,
|
||||
byte: u8,
|
||||
buf: &'a mut Vec<u8>,
|
||||
read: usize,
|
||||
cfg_io_util! {
|
||||
/// Future for the [`read_until`](crate::io::AsyncBufReadExt::read_until) method.
|
||||
#[derive(Debug)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct ReadUntil<'a, R: ?Sized> {
|
||||
reader: &'a mut R,
|
||||
byte: u8,
|
||||
buf: &'a mut Vec<u8>,
|
||||
read: usize,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn read_until<'a, R>(
|
||||
|
||||
+37
-35
@@ -4,42 +4,44 @@ use std::io;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
/// An async reader which yields one byte over and over and over and over and
|
||||
/// over and...
|
||||
///
|
||||
/// This struct is generally created by calling [`repeat`][repeat]. Please
|
||||
/// see the documentation of `repeat()` for more details.
|
||||
///
|
||||
/// This is an asynchronous version of [`std::io::Repeat`][std].
|
||||
///
|
||||
/// [repeat]: fn.repeat.html
|
||||
/// [std]: https://doc.rust-lang.org/std/io/struct.Repeat.html
|
||||
#[derive(Debug)]
|
||||
pub struct Repeat {
|
||||
byte: u8,
|
||||
}
|
||||
cfg_io_util! {
|
||||
/// An async reader which yields one byte over and over and over and over and
|
||||
/// over and...
|
||||
///
|
||||
/// This struct is generally created by calling [`repeat`][repeat]. Please
|
||||
/// see the documentation of `repeat()` for more details.
|
||||
///
|
||||
/// This is an asynchronous version of [`std::io::Repeat`][std].
|
||||
///
|
||||
/// [repeat]: fn.repeat.html
|
||||
/// [std]: https://doc.rust-lang.org/std/io/struct.Repeat.html
|
||||
#[derive(Debug)]
|
||||
pub struct Repeat {
|
||||
byte: u8,
|
||||
}
|
||||
|
||||
/// Creates an instance of an async reader that infinitely repeats one byte.
|
||||
///
|
||||
/// All reads from this reader will succeed by filling the specified buffer with
|
||||
/// the given byte.
|
||||
///
|
||||
/// This is an asynchronous version of [`std::io::repeat`][std].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # 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
|
||||
pub fn repeat(byte: u8) -> Repeat {
|
||||
Repeat { byte }
|
||||
/// Creates an instance of an async reader that infinitely repeats one byte.
|
||||
///
|
||||
/// All reads from this reader will succeed by filling the specified buffer with
|
||||
/// the given byte.
|
||||
///
|
||||
/// This is an asynchronous version of [`std::io::repeat`][std].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # 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
|
||||
pub fn repeat(byte: u8) -> Repeat {
|
||||
Repeat { byte }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncRead for Repeat {
|
||||
|
||||
@@ -5,12 +5,14 @@ use std::io;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
/// A future used to shutdown an I/O object.
|
||||
///
|
||||
/// Created by the [`AsyncWriteExt::shutdown`] function.
|
||||
#[derive(Debug)]
|
||||
pub struct Shutdown<'a, A: ?Sized> {
|
||||
a: &'a mut A,
|
||||
cfg_io_util! {
|
||||
/// A future used to shutdown an I/O object.
|
||||
///
|
||||
/// Created by the [`AsyncWriteExt::shutdown`] function.
|
||||
#[derive(Debug)]
|
||||
pub struct Shutdown<'a, A: ?Sized> {
|
||||
a: &'a mut A,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a future which will shutdown an I/O object.
|
||||
|
||||
+34
-32
@@ -5,39 +5,41 @@ use std::io;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
/// An async writer which will move data into the void.
|
||||
///
|
||||
/// This struct is generally created by calling [`sink`][sink]. Please
|
||||
/// see the documentation of `sink()` for more details.
|
||||
///
|
||||
/// This is an asynchronous version of `std::io::Sink`.
|
||||
///
|
||||
/// [sink]: fn.sink.html
|
||||
pub struct Sink {
|
||||
_p: (),
|
||||
}
|
||||
cfg_io_util! {
|
||||
/// An async writer which will move data into the void.
|
||||
///
|
||||
/// This struct is generally created by calling [`sink`][sink]. Please
|
||||
/// see the documentation of `sink()` for more details.
|
||||
///
|
||||
/// This is an asynchronous version of `std::io::Sink`.
|
||||
///
|
||||
/// [sink]: fn.sink.html
|
||||
pub struct Sink {
|
||||
_p: (),
|
||||
}
|
||||
|
||||
/// Creates an instance of an async writer which will successfully consume all
|
||||
/// data.
|
||||
///
|
||||
/// 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
|
||||
/// inspected.
|
||||
///
|
||||
/// This is an asynchronous version of `std::io::sink`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// # use tokio::io::{self, AsyncWriteExt};
|
||||
/// # async fn dox() {
|
||||
/// let buffer = vec![1, 2, 3, 5, 8];
|
||||
/// let num_bytes = io::sink().write(&buffer).await.unwrap();
|
||||
/// assert_eq!(num_bytes, 5);
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn sink() -> Sink {
|
||||
Sink { _p: () }
|
||||
/// Creates an instance of an async writer which will successfully consume all
|
||||
/// data.
|
||||
///
|
||||
/// 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
|
||||
/// inspected.
|
||||
///
|
||||
/// This is an asynchronous version of `std::io::sink`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// # use tokio::io::{self, AsyncWriteExt};
|
||||
/// # async fn dox() {
|
||||
/// let buffer = vec![1, 2, 3, 5, 8];
|
||||
/// let num_bytes = io::sink().write(&buffer).await.unwrap();
|
||||
/// assert_eq!(num_bytes, 5);
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn sink() -> Sink {
|
||||
Sink { _p: () }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncWrite for Sink {
|
||||
|
||||
@@ -11,6 +11,7 @@ pin_project! {
|
||||
/// Stream for the [`split`](crate::io::AsyncBufReadExt::split) method.
|
||||
#[derive(Debug)]
|
||||
#[must_use = "streams do nothing unless polled"]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
|
||||
pub struct Split<R> {
|
||||
#[pin]
|
||||
reader: R,
|
||||
|
||||
@@ -10,6 +10,7 @@ pin_project! {
|
||||
/// Stream for the [`take`](super::AsyncReadExt::take) method.
|
||||
#[derive(Debug)]
|
||||
#[must_use = "streams do nothing unless you `.await` or poll them"]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
|
||||
pub struct Take<R> {
|
||||
#[pin]
|
||||
inner: R,
|
||||
|
||||
@@ -5,12 +5,14 @@ use std::io;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
/// A future to write some of the buffer to an `AsyncWrite`.
|
||||
#[derive(Debug)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct Write<'a, W: ?Sized> {
|
||||
writer: &'a mut W,
|
||||
buf: &'a [u8],
|
||||
cfg_io_util! {
|
||||
/// A future to write some of the buffer to an `AsyncWrite`.
|
||||
#[derive(Debug)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct Write<'a, W: ?Sized> {
|
||||
writer: &'a mut W,
|
||||
buf: &'a [u8],
|
||||
}
|
||||
}
|
||||
|
||||
/// Tries to write some bytes from the given `buf` to the writer in an
|
||||
|
||||
@@ -6,11 +6,13 @@ use std::mem;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct WriteAll<'a, W: ?Sized> {
|
||||
writer: &'a mut W,
|
||||
buf: &'a [u8],
|
||||
cfg_io_util! {
|
||||
#[derive(Debug)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct WriteAll<'a, W: ?Sized> {
|
||||
writer: &'a mut W,
|
||||
buf: &'a [u8],
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn write_all<'a, W>(writer: &'a mut W, buf: &'a [u8]) -> WriteAll<'a, W>
|
||||
|
||||
+2
-1
@@ -10,6 +10,7 @@
|
||||
no_crate_inject,
|
||||
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.
|
||||
//!
|
||||
@@ -71,7 +72,7 @@
|
||||
//! [`tokio::task`]: crate::task
|
||||
//! [`spawn`]: crate::task::spawn()
|
||||
//! [`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
|
||||
//! need to communicate or share data. These include:
|
||||
|
||||
+38
-7
@@ -12,7 +12,11 @@ macro_rules! cfg_resource_drivers {
|
||||
|
||||
macro_rules! cfg_blocking {
|
||||
($($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 {
|
||||
($($item:item)*) => {
|
||||
$( #[cfg(feature = "dns")] $item )*
|
||||
$(
|
||||
#[cfg(feature = "dns")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "dns")))]
|
||||
$item
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -66,25 +80,40 @@ macro_rules! cfg_io_blocking {
|
||||
|
||||
macro_rules! cfg_io_driver {
|
||||
($($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 {
|
||||
($($item:item)*) => {
|
||||
$( #[cfg(not(feature = "io-driver"))] $item )*
|
||||
$(
|
||||
#[cfg(not(feature = "io-driver"))]
|
||||
$item
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! cfg_io_std {
|
||||
($($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 {
|
||||
($($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)*) => {
|
||||
$(
|
||||
#[cfg(feature = "macros")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
|
||||
#[doc(inline)]
|
||||
$item
|
||||
)*
|
||||
@@ -120,6 +150,7 @@ macro_rules! cfg_process {
|
||||
($($item:item)*) => {
|
||||
$(
|
||||
#[cfg(feature = "process")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "process")))]
|
||||
#[cfg(not(loom))]
|
||||
$item
|
||||
)*
|
||||
|
||||
@@ -101,10 +101,14 @@
|
||||
//! While similar to the standard library, this crate's `Child` type differs
|
||||
//! importantly in the behavior of `drop`. In the standard library, a 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
|
||||
//! `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"]
|
||||
#[cfg(unix)]
|
||||
|
||||
Reference in New Issue
Block a user