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 F: FnOnce(&mut Context<'_>) -> R,
37 {
38 assert_future::<R, _>(Lazy { f: Some(f) })
39 }
40
41 impl<F, R> FusedFuture for Lazy<F>
42 where F: FnOnce(&mut Context<'_>) -> R,
43 {
is_terminated(&self) -> bool44 fn is_terminated(&self) -> bool { self.f.is_none() }
45 }
46
47 impl<F, R> Future for Lazy<F>
48 where F: FnOnce(&mut Context<'_>) -> R,
49 {
50 type Output = R;
51
poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<R>52 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<R> {
53 Poll::Ready((self.f.take().expect("Lazy polled after completion"))(cx))
54 }
55 }
56