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