idb/request/store/futures/
macros.rs

1macro_rules! impl_store_request_future {
2    ($type: ident, $request: ty, $return_type: ty, $doc: expr) => {
3        #[cfg_attr(any(docsrs, feature = "doc"), doc(cfg(feature = "futures")))]
4        #[doc = $doc]
5        pub struct $type {
6            _inner: $request,
7            success_receiver: tokio::sync::oneshot::Receiver<Result<$return_type, Error>>,
8            error_receiver: tokio::sync::oneshot::Receiver<Error>,
9        }
10
11        #[cfg_attr(any(docsrs, feature = "doc"), doc(cfg(feature = "futures")))]
12        impl std::future::IntoFuture for $request {
13            type Output = <Self::IntoFuture as std::future::Future>::Output;
14
15            type IntoFuture = $type;
16
17            fn into_future(mut self) -> Self::IntoFuture {
18                let (error_sender, error_receiver) = tokio::sync::oneshot::channel();
19                let (success_sender, success_receiver) = tokio::sync::oneshot::channel();
20
21                crate::Request::on_error(&mut self, move |event| {
22                    let result = crate::StoreEvent::error(&event);
23                    let _ = error_sender.send(result);
24                });
25
26                crate::Request::on_success(&mut self, move |event| {
27                    let result = crate::StoreEvent::result(&event);
28                    let _ = success_sender.send(result);
29                });
30
31                $type {
32                    _inner: self,
33                    success_receiver,
34                    error_receiver,
35                }
36            }
37        }
38
39        impl std::future::Future for $type {
40            type Output = Result<$return_type, crate::Error>;
41
42            fn poll(
43                self: std::pin::Pin<&mut Self>,
44                cx: &mut std::task::Context<'_>,
45            ) -> std::task::Poll<Self::Output> {
46                let this = self.get_mut();
47
48                if let std::task::Poll::Ready(err) =
49                    std::pin::Pin::new(&mut this.error_receiver).poll(cx)
50                {
51                    return match err {
52                        Ok(err) => std::task::Poll::Ready(Err(err)),
53                        Err(_) => std::task::Poll::Ready(Err(Error::OneshotChannelReceiveError)),
54                    };
55                }
56
57                if let std::task::Poll::Ready(result) =
58                    std::pin::Pin::new(&mut this.success_receiver).poll(cx)
59                {
60                    return match result {
61                        Ok(result) => std::task::Poll::Ready(result),
62                        Err(_) => std::task::Poll::Ready(Err(Error::OneshotChannelReceiveError)),
63                    };
64                }
65
66                std::task::Poll::Pending
67            }
68        }
69    };
70}