diff options
Diffstat (limited to 'third_party/rust/futures/src')
-rw-r--r-- | third_party/rust/futures/src/lib.rs | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/third_party/rust/futures/src/lib.rs b/third_party/rust/futures/src/lib.rs new file mode 100644 index 0000000000..b972f51754 --- /dev/null +++ b/third_party/rust/futures/src/lib.rs @@ -0,0 +1,260 @@ +//! Abstractions for asynchronous programming. +//! +//! This crate provides a number of core abstractions for writing asynchronous +//! code: +//! +//! - [Futures](crate::future) are single eventual values produced by +//! asynchronous computations. Some programming languages (e.g. JavaScript) +//! call this concept "promise". +//! - [Streams](crate::stream) represent a series of values +//! produced asynchronously. +//! - [Sinks](crate::sink) provide support for asynchronous writing of +//! data. +//! - [Executors](crate::executor) are responsible for running asynchronous +//! tasks. +//! +//! The crate also contains abstractions for [asynchronous I/O](crate::io) and +//! [cross-task communication](crate::channel). +//! +//! Underlying all of this is the *task system*, which is a form of lightweight +//! threading. Large asynchronous computations are built up using futures, +//! streams and sinks, and then spawned as independent tasks that are run to +//! completion, but *do not block* the thread running them. +//! +//! The following example describes how the task system context is built and used +//! within macros and keywords such as async and await!. +//! +//! ```rust +//! # use futures::channel::mpsc; +//! # use futures::executor; ///standard executors to provide a context for futures and streams +//! # use futures::executor::ThreadPool; +//! # use futures::StreamExt; +//! # +//! fn main() { +//! # { +//! let pool = ThreadPool::new().expect("Failed to build pool"); +//! let (tx, rx) = mpsc::unbounded::<i32>(); +//! +//! // Create a future by an async block, where async is responsible for an +//! // implementation of Future. At this point no executor has been provided +//! // to this future, so it will not be running. +//! let fut_values = async { +//! // Create another async block, again where the Future implementation +//! // is generated by async. Since this is inside of a parent async block, +//! // it will be provided with the executor of the parent block when the parent +//! // block is executed. +//! // +//! // This executor chaining is done by Future::poll whose second argument +//! // is a std::task::Context. This represents our executor, and the Future +//! // implemented by this async block can be polled using the parent async +//! // block's executor. +//! let fut_tx_result = async move { +//! (0..100).for_each(|v| { +//! tx.unbounded_send(v).expect("Failed to send"); +//! }) +//! }; +//! +//! // Use the provided thread pool to spawn the generated future +//! // responsible for transmission +//! pool.spawn_ok(fut_tx_result); +//! +//! let fut_values = rx +//! .map(|v| v * 2) +//! .collect(); +//! +//! // Use the executor provided to this async block to wait for the +//! // future to complete. +//! fut_values.await +//! }; +//! +//! // Actually execute the above future, which will invoke Future::poll and +//! // subsequently chain appropriate Future::poll and methods needing executors +//! // to drive all futures. Eventually fut_values will be driven to completion. +//! let values: Vec<i32> = executor::block_on(fut_values); +//! +//! println!("Values={:?}", values); +//! # } +//! # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 +//! } +//! ``` +//! +//! The majority of examples and code snippets in this crate assume that they are +//! inside an async block as written above. + +#![cfg_attr(not(feature = "std"), no_std)] +#![warn( + missing_debug_implementations, + missing_docs, + rust_2018_idioms, + single_use_lifetimes, + unreachable_pub +)] +#![doc(test( + no_crate_inject, + attr( + deny(warnings, rust_2018_idioms, single_use_lifetimes), + allow(dead_code, unused_assignments, unused_variables) + ) +))] +#![cfg_attr(docsrs, feature(doc_cfg))] + +#[cfg(all(feature = "bilock", not(feature = "unstable")))] +compile_error!("The `bilock` feature requires the `unstable` feature as an explicit opt-in to unstable features"); + +#[doc(no_inline)] +pub use futures_core::future::{Future, TryFuture}; +#[doc(no_inline)] +pub use futures_util::future::{FutureExt, TryFutureExt}; + +#[doc(no_inline)] +pub use futures_core::stream::{Stream, TryStream}; +#[doc(no_inline)] +pub use futures_util::stream::{StreamExt, TryStreamExt}; + +#[doc(no_inline)] +pub use futures_sink::Sink; +#[doc(no_inline)] +pub use futures_util::sink::SinkExt; + +#[cfg(feature = "std")] +#[doc(no_inline)] +pub use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite}; +#[cfg(feature = "std")] +#[doc(no_inline)] +pub use futures_util::{AsyncBufReadExt, AsyncReadExt, AsyncSeekExt, AsyncWriteExt}; + +// Macro reexports +pub use futures_core::ready; // Readiness propagation +pub use futures_util::pin_mut; +#[cfg(feature = "std")] +#[cfg(feature = "async-await")] +pub use futures_util::select; +#[cfg(feature = "async-await")] +pub use futures_util::{join, pending, poll, select_biased, try_join}; // Async-await + +// Module reexports +#[doc(inline)] +pub use futures_util::{future, never, sink, stream, task}; + +#[cfg(feature = "std")] +#[cfg(feature = "async-await")] +pub use futures_util::stream_select; + +#[cfg(feature = "alloc")] +#[doc(inline)] +pub use futures_channel as channel; +#[cfg(feature = "alloc")] +#[doc(inline)] +pub use futures_util::lock; + +#[cfg(feature = "std")] +#[doc(inline)] +pub use futures_util::io; + +#[cfg(feature = "executor")] +#[cfg_attr(docsrs, doc(cfg(feature = "executor")))] +pub mod executor { + //! Built-in executors and related tools. + //! + //! All asynchronous computation occurs within an executor, which is + //! capable of spawning futures as tasks. This module provides several + //! built-in executors, as well as tools for building your own. + //! + //! + //! This module is only available when the `executor` feature of this + //! library is activated. + //! + //! # Using a thread pool (M:N task scheduling) + //! + //! Most of the time tasks should be executed on a [thread pool](ThreadPool). + //! A small set of worker threads can handle a very large set of spawned tasks + //! (which are much lighter weight than threads). Tasks spawned onto the pool + //! with the [`spawn_ok`](ThreadPool::spawn_ok) function will run ambiently on + //! the created threads. + //! + //! # Spawning additional tasks + //! + //! Tasks can be spawned onto a spawner by calling its [`spawn_obj`] method + //! directly. In the case of `!Send` futures, [`spawn_local_obj`] can be used + //! instead. + //! + //! # Single-threaded execution + //! + //! In addition to thread pools, it's possible to run a task (and the tasks + //! it spawns) entirely within a single thread via the [`LocalPool`] executor. + //! Aside from cutting down on synchronization costs, this executor also makes + //! it possible to spawn non-`Send` tasks, via [`spawn_local_obj`]. The + //! [`LocalPool`] is best suited for running I/O-bound tasks that do relatively + //! little work between I/O operations. + //! + //! There is also a convenience function [`block_on`] for simply running a + //! future to completion on the current thread. + //! + //! [`spawn_obj`]: https://docs.rs/futures/0.3/futures/task/trait.Spawn.html#tymethod.spawn_obj + //! [`spawn_local_obj`]: https://docs.rs/futures/0.3/futures/task/trait.LocalSpawn.html#tymethod.spawn_local_obj + + pub use futures_executor::{ + block_on, block_on_stream, enter, BlockingStream, Enter, EnterError, LocalPool, + LocalSpawner, + }; + + #[cfg(feature = "thread-pool")] + #[cfg_attr(docsrs, doc(cfg(feature = "thread-pool")))] + pub use futures_executor::{ThreadPool, ThreadPoolBuilder}; +} + +#[cfg(feature = "compat")] +#[cfg_attr(docsrs, doc(cfg(feature = "compat")))] +pub mod compat { + //! Interop between `futures` 0.1 and 0.3. + //! + //! This module is only available when the `compat` feature of this + //! library is activated. + + pub use futures_util::compat::{ + Compat, Compat01As03, Compat01As03Sink, CompatSink, Executor01As03, Executor01CompatExt, + Executor01Future, Future01CompatExt, Sink01CompatExt, Stream01CompatExt, + }; + + #[cfg(feature = "io-compat")] + #[cfg_attr(docsrs, doc(cfg(feature = "io-compat")))] + pub use futures_util::compat::{AsyncRead01CompatExt, AsyncWrite01CompatExt}; +} + +pub mod prelude { + //! A "prelude" for crates using the `futures` crate. + //! + //! This prelude is similar to the standard library's prelude in that you'll + //! almost always want to import its entire contents, but unlike the + //! standard library's prelude you'll have to do so manually: + //! + //! ``` + //! # #[allow(unused_imports)] + //! use futures::prelude::*; + //! ``` + //! + //! The prelude may grow over time as additional items see ubiquitous use. + + pub use crate::future::{self, Future, TryFuture}; + pub use crate::sink::{self, Sink}; + pub use crate::stream::{self, Stream, TryStream}; + + #[doc(no_inline)] + #[allow(unreachable_pub)] + pub use crate::future::{FutureExt as _, TryFutureExt as _}; + #[doc(no_inline)] + pub use crate::sink::SinkExt as _; + #[doc(no_inline)] + #[allow(unreachable_pub)] + pub use crate::stream::{StreamExt as _, TryStreamExt as _}; + + #[cfg(feature = "std")] + pub use crate::io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite}; + + #[cfg(feature = "std")] + #[doc(no_inline)] + #[allow(unreachable_pub)] + pub use crate::io::{ + AsyncBufReadExt as _, AsyncReadExt as _, AsyncSeekExt as _, AsyncWriteExt as _, + }; +} |