futures_lite/
lib.rs

1//! Futures, streams, and async I/O combinators.
2//!
3//! This crate is a subset of [futures] that compiles an order of magnitude faster, fixes minor
4//! warts in its API, fills in some obvious gaps, and removes almost all unsafe code from it.
5//!
6//! In short, this crate aims to be more enjoyable than [futures] but still fully compatible with
7//! it.
8//!
9//! [futures]: https://docs.rs/futures
10//!
11//! # Examples
12//!
13#![cfg_attr(feature = "std", doc = "```no_run")]
14#![cfg_attr(not(feature = "std"), doc = "```ignore")]
15//! use futures_lite::future;
16//!
17//! fn main() {
18//!     future::block_on(async {
19//!         println!("Hello world!");
20//!     })
21//! }
22//! ```
23
24#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
25#![cfg_attr(not(feature = "std"), no_std)]
26
27// TODO: These hidden re-exports are deprecated and should eventually be removed.
28#[cfg(feature = "std")]
29#[doc(hidden)]
30pub use crate::io::{
31    AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, AsyncWrite,
32    AsyncWriteExt,
33};
34#[doc(hidden)]
35pub use crate::{
36    future::{Future, FutureExt},
37    stream::{Stream, StreamExt},
38};
39
40pub mod future;
41pub mod prelude;
42pub mod stream;
43
44#[cfg(feature = "std")]
45pub mod io;
46
47/// Unwraps `Poll<T>` or returns [`Pending`][`core::task::Poll::Pending`].
48///
49/// # Examples
50///
51/// ```
52/// use futures_lite::{future, prelude::*, ready};
53/// use std::pin::Pin;
54/// use std::task::{Context, Poll};
55///
56/// fn do_poll(cx: &mut Context<'_>) -> Poll<()> {
57///     let mut fut = future::ready(42);
58///     let fut = Pin::new(&mut fut);
59///
60///     let num = ready!(fut.poll(cx));
61///     # drop(num);
62///     // ... use num
63///
64///     Poll::Ready(())
65/// }
66/// ```
67///
68/// The `ready!` call expands to:
69///
70/// ```
71/// # use futures_lite::{future, prelude::*, ready};
72/// # use std::pin::Pin;
73/// # use std::task::{Context, Poll};
74/// #
75/// # fn do_poll(cx: &mut Context<'_>) -> Poll<()> {
76///     # let mut fut = future::ready(42);
77///     # let fut = Pin::new(&mut fut);
78///     #
79/// let num = match fut.poll(cx) {
80///     Poll::Ready(t) => t,
81///     Poll::Pending => return Poll::Pending,
82/// };
83///     # drop(num);
84///     # // ... use num
85///     #
86///     # Poll::Ready(())
87/// # }
88/// ```
89#[macro_export]
90macro_rules! ready {
91    ($e:expr $(,)?) => {
92        match $e {
93            core::task::Poll::Ready(t) => t,
94            core::task::Poll::Pending => return core::task::Poll::Pending,
95        }
96    };
97}
98
99/// Pins a variable of type `T` on the stack and rebinds it as `Pin<&mut T>`.
100///
101/// ```
102/// use futures_lite::{future, pin};
103/// use std::fmt::Debug;
104/// use std::future::Future;
105/// use std::pin::Pin;
106/// use std::time::Instant;
107///
108/// // Inspects each invocation of `Future::poll()`.
109/// async fn inspect<T: Debug>(f: impl Future<Output = T>) -> T {
110///     pin!(f);
111///     future::poll_fn(|cx| dbg!(f.as_mut().poll(cx))).await
112/// }
113///
114/// # spin_on::spin_on(async {
115/// let f = async { 1 + 2 };
116/// inspect(f).await;
117/// # })
118/// ```
119#[macro_export]
120macro_rules! pin {
121    ($($x:ident),* $(,)?) => {
122        $(
123            let mut $x = $x;
124            #[allow(unused_mut)]
125            let mut $x = unsafe {
126                core::pin::Pin::new_unchecked(&mut $x)
127            };
128        )*
129    }
130}