• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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