• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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