nativeshell_core/util/
future.rs1use std::{cell::RefCell, rc::Rc, task::Poll};
2
3use futures::Future;
4
5struct State<T> {
10 waker: Option<std::task::Waker>,
11 data: Option<T>,
12}
13
14pub struct FutureCompleter<T> {
15 state: Rc<RefCell<State<T>>>,
16}
17
18impl<T> FutureCompleter<T> {
19 pub fn new() -> (CompletableFuture<T>, FutureCompleter<T>) {
20 let state = Rc::new(RefCell::new(State {
21 waker: None,
22 data: None,
23 }));
24 (
25 CompletableFuture {
26 state: state.clone(),
27 },
28 FutureCompleter { state },
29 )
30 }
31
32 pub fn complete(self, data: T) {
33 let waker = {
34 let mut state = self.state.borrow_mut();
35 state.data.replace(data);
36 state.waker.take()
37 };
38 if let Some(waker) = waker {
39 waker.wake();
40 }
41 }
42}
43
44pub struct CompletableFuture<T> {
45 state: Rc<RefCell<State<T>>>,
46}
47
48impl<T> Future for CompletableFuture<T> {
49 type Output = T;
50
51 fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
52 let mut state = self.state.borrow_mut();
53 let data = state.data.take();
54 match data {
55 Some(data) => Poll::Ready(data),
56 None => {
57 state.waker.get_or_insert_with(|| cx.waker().clone());
58 Poll::Pending
59 }
60 }
61 }
62}