1use futures::future::{FusedFuture, Shared};
6use futures::{Future, FutureExt};
7use std::task::{Context, Poll};
8
9use crate::DropWatch;
10
11#[derive(Clone)]
13#[must_use = "futures do nothing unless you await or poll them"]
14pub struct Dropped(Shared<futures::channel::oneshot::Receiver<()>>);
15
16impl Dropped {
17 pub fn new<DW: DropWatch<U> + ?Sized, U: ?Sized>(watchable: &DW) -> Self {
18 let (sender, receiver) = futures::channel::oneshot::channel();
19 DropWatch::watch(watchable, move |_| {
20 let _ = sender.send(());
21 });
22 Self(receiver.shared())
23 }
24}
25
26impl Future for Dropped {
27 type Output = ();
28
29 fn poll(mut self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
30 self.0.poll_unpin(cx).map(|_| ())
31 }
32}
33
34impl FusedFuture for Dropped {
35 fn is_terminated(&self) -> bool {
36 self.0.is_terminated()
37 }
38}
39
40#[cfg(test)]
41mod tests {
42 use async_utils::PollExt;
43 use futures_test::task::new_count_waker;
44
45 use super::*;
46 use crate::Vigil;
47
48 #[test]
49 fn obits() {
50 let v = Vigil::new(());
51
52 let mut obit = Vigil::dropped(&v);
53 let mut obit2 = Vigil::dropped(&v);
54 let mut obit_never_polled = Vigil::dropped(&v);
55
56 let (waker, count) = new_count_waker();
57
58 let mut cx = Context::from_waker(&waker);
59
60 obit.poll_unpin(&mut cx).expect_pending("shouldn't be done");
61 obit2.poll_unpin(&mut cx).expect_pending("shouldn't be done");
62
63 drop(v);
65 assert_eq!(2, count.get());
67
68 obit.poll_unpin(&mut cx).expect("should be done");
70 obit2.poll_unpin(&mut cx).expect("should also be done");
71
72 obit_never_polled.poll_unpin(&mut cx).expect("be done");
74 }
75}