async_result/
lib.rs

1use futures_channel::oneshot;
2use std::future::Future;
3
4pub use futures_channel::oneshot::Canceled;
5
6pub struct Completer<T> {
7    tx: oneshot::Sender<T>,
8}
9
10impl<T> Completer<T> {
11    pub fn try_complete(self, res: T) -> Result<(), T> {
12        self.tx.send(res)
13    }
14
15    pub fn complete(self, res: T) {
16        self.try_complete(res).ok();
17    }
18}
19
20pub struct AsyncResult {}
21
22impl AsyncResult {
23    pub async fn with<T>(f: impl FnOnce(Completer<T>)) -> Result<T, Canceled> {
24        let (tx, rx) = oneshot::channel();
25        f(Completer { tx });
26        rx.await
27    }
28
29    pub async fn with_async<T, F: Future<Output = ()>>(
30        f: impl FnOnce(Completer<T>) -> F,
31    ) -> Result<T, Canceled> {
32        let (tx, rx) = oneshot::channel();
33        f(Completer { tx }).await;
34        rx.await
35    }
36
37    pub fn new_split<T>() -> (Completer<T>, impl Future<Output = Result<T, Canceled>>) {
38        let (tx, rx) = oneshot::channel();
39        let fut = async { rx.await };
40        (Completer { tx }, fut)
41    }
42}