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
//! 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)] // TODO: These hidden re-exports are deprecated and should eventually be removed. #[cfg(feature = "std")] #[doc(hidden)] pub use crate::io::{ AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, AsyncWrite, AsyncWriteExt, }; #[doc(hidden)] 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::FutureExt; /// use futures_lite::ready; /// use std::future::Future; /// use std::pin::Pin; /// use std::task::{Context, Poll}; /// /// // Polls two futures and sums their results. /// fn poll_sum( /// cx: &mut Context<'_>, /// a: Pin<&mut impl Future<Output = i32>>, /// b: Pin<&mut impl Future<Output = i32>>, /// ) -> Poll<i32> { /// let x = ready!(a.poll(cx)); /// let y = ready!(b.poll(cx)); /// Poll::Ready(x + y) /// } /// ``` #[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) }; )* } }