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}