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#![allow(clippy::needless_borrow)] // suggest code that doesn't work on MSRV
27
28#[cfg(feature = "std")]
29#[doc(no_inline)]
30pub use crate::io::{
31 AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, AsyncWrite,
32 AsyncWriteExt,
33};
34#[doc(no_inline)]
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}
131