1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
//! Futures, streams, and async I/O combinators.
//!
//! This crate is a subset of [futures] that compiles an order of magnitude faster, fixes minor
//! warts in its API, fills in some obvious gaps, and removes almost all unsafe code from it.
//!
//! In short, this crate aims to be more enjoyable than [futures] but still fully compatible with
//! it.
//!
//! [futures]: https://docs.rs/futures
//!
//! # Examples
//!
#![cfg_attr(feature = "std", doc = "```no_run")]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
//! use futures_lite::future;
//!
//! fn main() {
//! future::block_on(async {
//! println!("Hello world!");
//! })
//! }
//! ```
#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
#![cfg_attr(not(feature = "std"), no_std)]
#![allow(clippy::needless_borrow)] // suggest code that doesn't work on MSRV
#[cfg(feature = "std")]
#[doc(no_inline)]
pub use crate::io::{
AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, AsyncWrite,
AsyncWriteExt,
};
#[doc(no_inline)]
pub use crate::{
future::{Future, FutureExt},
stream::{Stream, StreamExt},
};
pub mod future;
pub mod prelude;
pub mod stream;
#[cfg(feature = "std")]
pub mod io;
/// Unwraps `Poll<T>` or returns [`Pending`][`core::task::Poll::Pending`].
///
/// # Examples
///
/// ```
/// use futures_lite::{future, prelude::*, ready};
/// use std::pin::Pin;
/// use std::task::{Context, Poll};
///
/// fn do_poll(cx: &mut Context<'_>) -> Poll<()> {
/// let mut fut = future::ready(42);
/// let fut = Pin::new(&mut fut);
///
/// let num = ready!(fut.poll(cx));
/// # drop(num);
/// // ... use num
///
/// Poll::Ready(())
/// }
/// ```
///
/// The `ready!` call expands to:
///
/// ```
/// # use futures_lite::{future, prelude::*, ready};
/// # use std::pin::Pin;
/// # use std::task::{Context, Poll};
/// #
/// # fn do_poll(cx: &mut Context<'_>) -> Poll<()> {
/// # let mut fut = future::ready(42);
/// # let fut = Pin::new(&mut fut);
/// #
/// let num = match fut.poll(cx) {
/// Poll::Ready(t) => t,
/// Poll::Pending => return Poll::Pending,
/// };
/// # drop(num);
/// # // ... use num
/// #
/// # Poll::Ready(())
/// # }
/// ```
#[macro_export]
macro_rules! ready {
($e:expr $(,)?) => {
match $e {
core::task::Poll::Ready(t) => t,
core::task::Poll::Pending => return core::task::Poll::Pending,
}
};
}
/// Pins a variable of type `T` on the stack and rebinds it as `Pin<&mut T>`.
///
/// ```
/// use futures_lite::{future, pin};
/// use std::fmt::Debug;
/// use std::future::Future;
/// use std::pin::Pin;
/// use std::time::Instant;
///
/// // Inspects each invocation of `Future::poll()`.
/// async fn inspect<T: Debug>(f: impl Future<Output = T>) -> T {
/// pin!(f);
/// future::poll_fn(|cx| dbg!(f.as_mut().poll(cx))).await
/// }
///
/// # spin_on::spin_on(async {
/// let f = async { 1 + 2 };
/// inspect(f).await;
/// # })
/// ```
#[macro_export]
macro_rules! pin {
($($x:ident),* $(,)?) => {
$(
let mut $x = $x;
#[allow(unused_mut)]
let mut $x = unsafe {
core::pin::Pin::new_unchecked(&mut $x)
};
)*
}
}