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//! The API for this crate is intentionally constrained. Please consult the [features list] for
10//! APIs that are occluded from this crate.
11//!
12//! [futures]: https://docs.rs/futures
13//! [features list]: https://github.com/smol-rs/futures-lite/blob/master/FEATURES.md
14//!
15//! # Examples
16//!
17#![cfg_attr(feature = "std", doc = "```no_run")]
18#![cfg_attr(not(feature = "std"), doc = "```ignore")]
19//! use futures_lite::future;
20//!
21//! fn main() {
22//!     future::block_on(async {
23//!         println!("Hello world!");
24//!     })
25//! }
26//! ```
27
28#![no_std]
29#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
30#![allow(clippy::needless_borrow)] // suggest code that doesn't work on MSRV
31#![doc(
32    html_favicon_url = "https://raw.githubusercontent.com/smol-rs/smol/master/assets/images/logo_fullsize_transparent.png"
33)]
34#![doc(
35    html_logo_url = "https://raw.githubusercontent.com/smol-rs/smol/master/assets/images/logo_fullsize_transparent.png"
36)]
37#![cfg_attr(docsrs, feature(doc_auto_cfg))]
38
39#[cfg(feature = "alloc")]
40extern crate alloc;
41
42#[cfg(feature = "std")]
43extern crate std;
44
45#[cfg(feature = "std")]
46#[doc(no_inline)]
47pub use crate::io::{
48    AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, AsyncWrite,
49    AsyncWriteExt,
50};
51#[doc(no_inline)]
52pub use crate::{
53    future::{Future, FutureExt},
54    stream::{Stream, StreamExt},
55};
56
57pub mod future;
58pub mod prelude;
59pub mod stream;
60
61#[cfg(feature = "std")]
62pub mod io;
63
64/// Unwraps `Poll<T>` or returns [`Pending`][`core::task::Poll::Pending`].
65///
66/// # Examples
67///
68/// ```
69/// use futures_lite::{future, prelude::*, ready};
70/// use std::pin::Pin;
71/// use std::task::{Context, Poll};
72///
73/// fn do_poll(cx: &mut Context<'_>) -> Poll<()> {
74///     let mut fut = future::ready(42);
75///     let fut = Pin::new(&mut fut);
76///
77///     let num = ready!(fut.poll(cx));
78///     # drop(num);
79///     // ... use num
80///
81///     Poll::Ready(())
82/// }
83/// ```
84///
85/// The `ready!` call expands to:
86///
87/// ```
88/// # use futures_lite::{future, prelude::*, ready};
89/// # use std::pin::Pin;
90/// # use std::task::{Context, Poll};
91/// #
92/// # fn do_poll(cx: &mut Context<'_>) -> Poll<()> {
93///     # let mut fut = future::ready(42);
94///     # let fut = Pin::new(&mut fut);
95///     #
96/// let num = match fut.poll(cx) {
97///     Poll::Ready(t) => t,
98///     Poll::Pending => return Poll::Pending,
99/// };
100///     # drop(num);
101///     # // ... use num
102///     #
103///     # Poll::Ready(())
104/// # }
105/// ```
106#[macro_export]
107macro_rules! ready {
108    ($e:expr $(,)?) => {
109        match $e {
110            core::task::Poll::Ready(t) => t,
111            core::task::Poll::Pending => return core::task::Poll::Pending,
112        }
113    };
114}
115
116/// Pins a variable of type `T` on the stack and rebinds it as `Pin<&mut T>`.
117///
118/// ```
119/// use futures_lite::{future, pin};
120/// use std::fmt::Debug;
121/// use std::future::Future;
122/// use std::pin::Pin;
123/// use std::time::Instant;
124///
125/// // Inspects each invocation of `Future::poll()`.
126/// async fn inspect<T: Debug>(f: impl Future<Output = T>) -> T {
127///     pin!(f);
128///     future::poll_fn(|cx| dbg!(f.as_mut().poll(cx))).await
129/// }
130///
131/// # spin_on::spin_on(async {
132/// let f = async { 1 + 2 };
133/// inspect(f).await;
134/// # })
135/// ```
136#[macro_export]
137macro_rules! pin {
138    ($($x:ident),* $(,)?) => {
139        $(
140            let mut $x = $x;
141            #[allow(unused_mut)]
142            let mut $x = unsafe {
143                core::pin::Pin::new_unchecked(&mut $x)
144            };
145        )*
146    }
147}