1 //! Abstractions for asynchronous programming. 2 //! 3 //! This crate provides a number of core abstractions for writing asynchronous 4 //! code: 5 //! 6 //! - [Futures](crate::future::Future) are single eventual values produced by 7 //! asynchronous computations. Some programming languages (e.g. JavaScript) 8 //! call this concept "promise". 9 //! - [Streams](crate::stream::Stream) represent a series of values 10 //! produced asynchronously. 11 //! - [Sinks](crate::sink::Sink) provide support for asynchronous writing of 12 //! data. 13 //! - [Executors](crate::executor) are responsible for running asynchronous 14 //! tasks. 15 //! 16 //! The crate also contains abstractions for [asynchronous I/O](crate::io) and 17 //! [cross-task communication](crate::channel). 18 //! 19 //! Underlying all of this is the *task system*, which is a form of lightweight 20 //! threading. Large asynchronous computations are built up using futures, 21 //! streams and sinks, and then spawned as independent tasks that are run to 22 //! completion, but *do not block* the thread running them. 23 //! 24 //! The following example describes how the task system context is built and used 25 //! within macros and keywords such as async and await!. 26 //! 27 //! ```rust 28 //! # use futures::channel::mpsc; 29 //! # use futures::executor; ///standard executors to provide a context for futures and streams 30 //! # use futures::executor::ThreadPool; 31 //! # use futures::StreamExt; 32 //! 33 //! fn main() { 34 //! let pool = ThreadPool::new().expect("Failed to build pool"); 35 //! let (tx, rx) = mpsc::unbounded::<i32>(); 36 //! 37 //! // Create a future by an async block, where async is responsible for an 38 //! // implementation of Future. At this point no executor has been provided 39 //! // to this future, so it will not be running. 40 //! let fut_values = async { 41 //! // Create another async block, again where the Future implementation 42 //! // is generated by async. Since this is inside of a parent async block, 43 //! // it will be provided with the executor of the parent block when the parent 44 //! // block is executed. 45 //! // 46 //! // This executor chaining is done by Future::poll whose second argument 47 //! // is a std::task::Context. This represents our executor, and the Future 48 //! // implemented by this async block can be polled using the parent async 49 //! // block's executor. 50 //! let fut_tx_result = async move { 51 //! (0..100).for_each(|v| { 52 //! tx.unbounded_send(v).expect("Failed to send"); 53 //! }) 54 //! }; 55 //! 56 //! // Use the provided thread pool to spawn the generated future 57 //! // responsible for transmission 58 //! pool.spawn_ok(fut_tx_result); 59 //! 60 //! let fut_values = rx 61 //! .map(|v| v * 2) 62 //! .collect(); 63 //! 64 //! // Use the executor provided to this async block to wait for the 65 //! // future to complete. 66 //! fut_values.await 67 //! }; 68 //! 69 //! // Actually execute the above future, which will invoke Future::poll and 70 //! // subsequenty chain appropriate Future::poll and methods needing executors 71 //! // to drive all futures. Eventually fut_values will be driven to completion. 72 //! let values: Vec<i32> = executor::block_on(fut_values); 73 //! 74 //! println!("Values={:?}", values); 75 //! } 76 //! ``` 77 //! 78 //! The majority of examples and code snippets in this crate assume that they are 79 //! inside an async block as written above. 80 81 #![cfg_attr(feature = "cfg-target-has-atomic", feature(cfg_target_has_atomic))] 82 #![cfg_attr(feature = "read-initializer", feature(read_initializer))] 83 84 #![cfg_attr(not(feature = "std"), no_std)] 85 86 #![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)] 87 // It cannot be included in the published code because this lints have false positives in the minimum required version. 88 #![cfg_attr(test, warn(single_use_lifetimes))] 89 #![warn(clippy::all)] 90 #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))] 91 92 #![cfg_attr(docsrs, feature(doc_cfg))] 93 94 #[cfg(all(feature = "cfg-target-has-atomic", not(feature = "unstable")))] 95 compile_error!("The `cfg-target-has-atomic` feature requires the `unstable` feature as an explicit opt-in to unstable features"); 96 97 #[cfg(all(feature = "bilock", not(feature = "unstable")))] 98 compile_error!("The `bilock` feature requires the `unstable` feature as an explicit opt-in to unstable features"); 99 100 #[cfg(all(feature = "read-initializer", not(feature = "unstable")))] 101 compile_error!("The `read-initializer` feature requires the `unstable` feature as an explicit opt-in to unstable features"); 102 103 #[doc(hidden)] 104 pub use futures_core::future::{Future, TryFuture}; 105 #[doc(hidden)] 106 pub use futures_util::future::{FutureExt, TryFutureExt}; 107 108 #[doc(hidden)] 109 pub use futures_core::stream::{Stream, TryStream}; 110 #[doc(hidden)] 111 pub use futures_util::stream::{StreamExt, TryStreamExt}; 112 113 #[doc(hidden)] 114 pub use futures_sink::Sink; 115 #[doc(hidden)] 116 pub use futures_util::sink::SinkExt; 117 118 #[cfg(feature = "std")] 119 #[doc(hidden)] 120 pub use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite}; 121 #[cfg(feature = "std")] 122 #[doc(hidden)] 123 pub use futures_util::{AsyncBufReadExt, AsyncReadExt, AsyncSeekExt, AsyncWriteExt}; 124 125 // Macro reexports 126 pub use futures_core::ready; // Readiness propagation 127 pub use futures_util::pin_mut; 128 #[cfg(feature = "std")] 129 #[cfg(feature = "async-await")] 130 pub use futures_util::select; 131 #[cfg(feature = "async-await")] 132 pub use futures_util::{join, pending, poll, select_biased, try_join}; // Async-await 133 134 // Module reexports 135 #[doc(inline)] 136 pub use futures_util::{future, never, sink, stream, task}; 137 138 #[cfg(feature = "alloc")] 139 #[doc(inline)] 140 pub use futures_channel as channel; 141 #[cfg(feature = "alloc")] 142 #[doc(inline)] 143 pub use futures_util::lock; 144 145 #[cfg(feature = "std")] 146 #[doc(inline)] 147 pub use futures_util::io; 148 149 #[cfg(feature = "executor")] 150 #[cfg_attr(docsrs, doc(cfg(feature = "executor")))] 151 #[doc(inline)] 152 pub use futures_executor as executor; 153 154 #[cfg(feature = "compat")] 155 #[cfg_attr(docsrs, doc(cfg(feature = "compat")))] 156 #[doc(inline)] 157 pub use futures_util::compat; 158 159 pub mod prelude { 160 //! A "prelude" for crates using the `futures` crate. 161 //! 162 //! This prelude is similar to the standard library's prelude in that you'll 163 //! almost always want to import its entire contents, but unlike the 164 //! standard library's prelude you'll have to do so manually: 165 //! 166 //! ``` 167 //! # #[allow(unused_imports)] 168 //! use futures::prelude::*; 169 //! ``` 170 //! 171 //! The prelude may grow over time as additional items see ubiquitous use. 172 173 pub use crate::future::{self, Future, TryFuture}; 174 pub use crate::sink::{self, Sink}; 175 pub use crate::stream::{self, Stream, TryStream}; 176 177 #[doc(no_inline)] 178 pub use crate::future::{FutureExt as _, TryFutureExt as _}; 179 #[doc(no_inline)] 180 pub use crate::sink::SinkExt as _; 181 #[doc(no_inline)] 182 pub use crate::stream::{StreamExt as _, TryStreamExt as _}; 183 184 #[cfg(feature = "std")] 185 pub use crate::io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite}; 186 187 #[cfg(feature = "std")] 188 #[doc(no_inline)] 189 pub use crate::io::{ 190 AsyncBufReadExt as _, AsyncReadExt as _, AsyncSeekExt as _, AsyncWriteExt as _, 191 }; 192 } 193