futures 0.3.7

An implementation of futures and streams featuring zero allocations, composability, and iterator-like interfaces.
Documentation
futures-0.3.7 has been yanked.
Abstractions for asynchronous programming. This crate provides a number of core abstractions for writing asynchronous code: - [Futures](crate::future::Future) are single eventual values produced by asynchronous computations. Some programming languages (e.g. JavaScript) call this concept "promise". - [Streams](crate::stream::Stream) represent a series of values produced asynchronously. - [Sinks](crate::sink::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::(); // 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 // subsequenty chain appropriate Future::poll and methods needing executors // to drive all futures. Eventually fut_values will be driven to completion. let values: Vec = executor::block_on(fut_values); println!("Values={:?}", values); } ``` The majority of examples and code snippets in this crate assume that they are inside an async block as written above.