1 use super::assert_future;
2 use core::pin::Pin;
3 use futures_core::future::{FusedFuture, Future};
4 use futures_core::task::{Context, Poll};
5
6 /// Future for the [`lazy`] function.
7 #[derive(Debug)]
8 #[must_use = "futures do nothing unless you `.await` or poll them"]
9 pub struct Lazy<F> {
10 f: Option<F>,
11 }
12
13 // safe because we never generate `Pin<&mut F>`
14 impl<F> Unpin for Lazy<F> {}
15
16 /// Creates a new future that allows delayed execution of a closure.
17 ///
18 /// The provided closure is only run once the future is polled.
19 ///
20 /// # Examples
21 ///
22 /// ```
23 /// # futures::executor::block_on(async {
24 /// use futures::future;
25 ///
26 /// let a = future::lazy(|_| 1);
27 /// assert_eq!(a.await, 1);
28 ///
29 /// let b = future::lazy(|_| -> i32 {
30 /// panic!("oh no!")
31 /// });
32 /// drop(b); // closure is never run
33 /// # });
34 /// ```
lazy<F, R>(f: F) -> Lazy<F> where F: FnOnce(&mut Context<'_>) -> R,35 pub fn lazy<F, R>(f: F) -> Lazy<F>
36 where
37 F: FnOnce(&mut Context<'_>) -> R,
38 {
39 assert_future::<R, _>(Lazy { f: Some(f) })
40 }
41
42 impl<F, R> FusedFuture for Lazy<F>
43 where
44 F: FnOnce(&mut Context<'_>) -> R,
45 {
is_terminated(&self) -> bool46 fn is_terminated(&self) -> bool {
47 self.f.is_none()
48 }
49 }
50
51 impl<F, R> Future for Lazy<F>
52 where
53 F: FnOnce(&mut Context<'_>) -> R,
54 {
55 type Output = R;
56
poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<R>57 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<R> {
58 Poll::Ready((self.f.take().expect("Lazy polled after completion"))(cx))
59 }
60 }
61