1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
use event_listener::{Event, EventListener};
#[must_use = "TimeHandlerGuard must be kept until the timer has performed it's side-effects"]
pub struct TimeHandlerGuard(Event);
impl TimeHandlerGuard {
pub(crate) fn new() -> (Self, TimeHandlerFinished) {
let event = Event::new();
let listener = event.listen();
(Self(event), TimeHandlerFinished(listener))
}
}
impl Drop for TimeHandlerGuard {
fn drop(&mut self) {
self.0.notify(1);
}
}
pub(crate) struct TimeHandlerFinished(EventListener);
impl TimeHandlerFinished {
pub(crate) async fn wait(self) {
self.0.await
}
}
#[cfg(test)]
mod test {
use crate::TimeHandlerGuard;
use futures_lite::future::poll_once;
use futures_lite::pin;
#[tokio::test]
async fn should_notify_once_time_handler_guard_is_dropped() {
let (guard, waiter) = TimeHandlerGuard::new();
let waiter_future = waiter.wait();
pin!(waiter_future);
assert!(
poll_once(waiter_future.as_mut()).await.is_none(),
"Waiter should have been pending before the guard is dropped",
);
drop(guard);
assert!(
poll_once(waiter_future.as_mut()).await.is_some(),
"Waiter should have been ready after the guard was dropped",
);
}
}