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