futures_test/future/
pending_once.rs1use futures_core::future::{Future, FusedFuture};
2use futures_core::task::{Context, Poll};
3use std::pin::Pin;
4use pin_utils::{unsafe_pinned, unsafe_unpinned};
5
6#[derive(Debug, Clone)]
13#[must_use = "futures do nothing unless you `.await` or poll them"]
14pub struct PendingOnce<Fut: Future> {
15 future: Fut,
16 polled_before: bool,
17}
18
19impl<Fut: Future> PendingOnce<Fut> {
20 unsafe_pinned!(future: Fut);
21 unsafe_unpinned!(polled_before: bool);
22
23 pub(super) fn new(future: Fut) -> Self {
24 Self {
25 future,
26 polled_before: false,
27 }
28 }
29}
30
31impl<Fut: Future> Future for PendingOnce<Fut> {
32 type Output = Fut::Output;
33
34 fn poll(
35 mut self: Pin<&mut Self>,
36 cx: &mut Context<'_>,
37 ) -> Poll<Self::Output> {
38 if self.polled_before {
39 self.as_mut().future().poll(cx)
40 } else {
41 *self.as_mut().polled_before() = true;
42 cx.waker().wake_by_ref();
43 Poll::Pending
44 }
45 }
46}
47
48impl<Fut: FusedFuture> FusedFuture for PendingOnce<Fut> {
49 fn is_terminated(&self) -> bool {
50 self.polled_before && self.future.is_terminated()
51 }
52}