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#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
29#![cfg_attr(not(feature = "std"), no_std)]
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
38#[cfg(feature = "std")]
39#[doc(no_inline)]
40pub use crate::io::{
41 AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, AsyncWrite,
42 AsyncWriteExt,
43};
44#[doc(no_inline)]
45pub use crate::{
46 future::{Future, FutureExt},
47 stream::{Stream, StreamExt},
48};
49
50pub mod future;
51pub mod prelude;
52pub mod stream;
53
54#[cfg(feature = "std")]
55pub mod io;
56
57/// Unwraps `Poll<T>` or returns [`Pending`][`core::task::Poll::Pending`].
58///
59/// # Examples
60///
61/// ```
62/// use futures_lite::{future, prelude::*, ready};
63/// use std::pin::Pin;
64/// use std::task::{Context, Poll};
65///
66/// fn do_poll(cx: &mut Context<'_>) -> Poll<()> {
67/// let mut fut = future::ready(42);
68/// let fut = Pin::new(&mut fut);
69///
70/// let num = ready!(fut.poll(cx));
71/// # drop(num);
72/// // ... use num
73///
74/// Poll::Ready(())
75/// }
76/// ```
77///
78/// The `ready!` call expands to:
79///
80/// ```
81/// # use futures_lite::{future, prelude::*, ready};
82/// # use std::pin::Pin;
83/// # use std::task::{Context, Poll};
84/// #
85/// # fn do_poll(cx: &mut Context<'_>) -> Poll<()> {
86/// # let mut fut = future::ready(42);
87/// # let fut = Pin::new(&mut fut);
88/// #
89/// let num = match fut.poll(cx) {
90/// Poll::Ready(t) => t,
91/// Poll::Pending => return Poll::Pending,
92/// };
93/// # drop(num);
94/// # // ... use num
95/// #
96/// # Poll::Ready(())
97/// # }
98/// ```
99#[macro_export]
100macro_rules! ready {
101 ($e:expr $(,)?) => {
102 match $e {
103 core::task::Poll::Ready(t) => t,
104 core::task::Poll::Pending => return core::task::Poll::Pending,
105 }
106 };
107}
108
109/// Pins a variable of type `T` on the stack and rebinds it as `Pin<&mut T>`.
110///
111/// ```
112/// use futures_lite::{future, pin};
113/// use std::fmt::Debug;
114/// use std::future::Future;
115/// use std::pin::Pin;
116/// use std::time::Instant;
117///
118/// // Inspects each invocation of `Future::poll()`.
119/// async fn inspect<T: Debug>(f: impl Future<Output = T>) -> T {
120/// pin!(f);
121/// future::poll_fn(|cx| dbg!(f.as_mut().poll(cx))).await
122/// }
123///
124/// # spin_on::spin_on(async {
125/// let f = async { 1 + 2 };
126/// inspect(f).await;
127/// # })
128/// ```
129#[macro_export]
130macro_rules! pin {
131 ($($x:ident),* $(,)?) => {
132 $(
133 let mut $x = $x;
134 #[allow(unused_mut)]
135 let mut $x = unsafe {
136 core::pin::Pin::new_unchecked(&mut $x)
137 };
138 )*
139 }
140}