1 use futures_core::future::{FusedFuture, Future};
2 use futures_core::task::{Context, Poll};
3 use pin_project::pin_project;
4 use std::pin::Pin;
5 
6 /// Combinator that guarantees one [`Poll::Pending`] before polling its inner
7 /// future.
8 ///
9 /// This is created by the
10 /// [`FutureTestExt::pending_once`](super::FutureTestExt::pending_once)
11 /// method.
12 #[pin_project]
13 #[derive(Debug, Clone)]
14 #[must_use = "futures do nothing unless you `.await` or poll them"]
15 pub struct PendingOnce<Fut> {
16     #[pin]
17     future: Fut,
18     polled_before: bool,
19 }
20 
21 impl<Fut: Future> PendingOnce<Fut> {
new(future: Fut) -> Self22     pub(super) fn new(future: Fut) -> Self {
23         Self { future, polled_before: false }
24     }
25 }
26 
27 impl<Fut: Future> Future for PendingOnce<Fut> {
28     type Output = Fut::Output;
29 
poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>30     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
31         let this = self.project();
32         if *this.polled_before {
33             this.future.poll(cx)
34         } else {
35             *this.polled_before = true;
36             cx.waker().wake_by_ref();
37             Poll::Pending
38         }
39     }
40 }
41 
42 impl<Fut: FusedFuture> FusedFuture for PendingOnce<Fut> {
is_terminated(&self) -> bool43     fn is_terminated(&self) -> bool {
44         self.polled_before && self.future.is_terminated()
45     }
46 }
47