futures_util/future/
lazy.rs1use core::mem;
5
6use futures_core::{Future, IntoFuture, Poll};
7use futures_core::task;
8
9#[derive(Debug)]
14#[must_use = "futures do nothing unless polled"]
15pub struct Lazy<R: IntoFuture, F> {
16 inner: _Lazy<R::Future, F>,
17}
18
19#[derive(Debug)]
20enum _Lazy<R, F> {
21 First(F),
22 Second(R),
23 Moved,
24}
25
26pub fn lazy<R, F>(f: F) -> Lazy<R, F>
49 where F: FnOnce(&mut task::Context) -> R,
50 R: IntoFuture
51{
52 Lazy {
53 inner: _Lazy::First(f),
54 }
55}
56
57impl<R, F> Lazy<R, F>
58 where F: FnOnce(&mut task::Context) -> R,
59 R: IntoFuture,
60{
61 fn get(&mut self, cx: &mut task::Context) -> &mut R::Future {
62 match self.inner {
63 _Lazy::First(_) => {}
64 _Lazy::Second(ref mut f) => return f,
65 _Lazy::Moved => panic!(), }
67 match mem::replace(&mut self.inner, _Lazy::Moved) {
68 _Lazy::First(f) => self.inner = _Lazy::Second(f(cx).into_future()),
69 _ => panic!(), }
71 match self.inner {
72 _Lazy::Second(ref mut f) => f,
73 _ => panic!(), }
75 }
76}
77
78impl<R, F> Future for Lazy<R, F>
79 where F: FnOnce(&mut task::Context) -> R,
80 R: IntoFuture,
81{
82 type Item = R::Item;
83 type Error = R::Error;
84
85 fn poll(&mut self, cx: &mut task::Context) -> Poll<R::Item, R::Error> {
86 self.get(cx).poll(cx)
87 }
88}