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}