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