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