1use super::assert_future;
2use core::pin::Pin;
3use futures_core::future::{FusedFuture, Future};
4use 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"]
9pub struct Lazy<F> {
10 f: Option<F>,
11}
12
13// safe because we never generate `Pin<&mut F>`
14impl<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/// ```
35pub fn lazy<F, R>(f: F) -> Lazy<F>
36where
37 F: FnOnce(&mut Context<'_>) -> R,
38{
39 assert_future::<R, _>(Lazy { f: Some(f) })
40}
41
42impl<F, R> FusedFuture for Lazy<F>
43where
44 F: FnOnce(&mut Context<'_>) -> R,
45{
46 fn is_terminated(&self) -> bool {
47 self.f.is_none()
48 }
49}
50
51impl<F, R> Future for Lazy<F>
52where
53 F: FnOnce(&mut Context<'_>) -> R,
54{
55 type Output = R;
56
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