reown_relay_client/websocket/
outbound.rs1use {
2 crate::{error::Error, ClientError},
3 pin_project::pin_project,
4 reown_relay_rpc::rpc::{Params, ServiceRequest},
5 std::{
6 future::Future,
7 marker::PhantomData,
8 pin::Pin,
9 task::{ready, Context, Poll},
10 },
11 tokio::sync::oneshot,
12};
13
14#[derive(Debug)]
17pub struct OutboundRequest {
18 pub(super) params: Params,
19 pub(super) tx: oneshot::Sender<Result<serde_json::Value, ClientError>>,
20}
21
22impl OutboundRequest {
23 pub(super) fn new(
24 params: Params,
25 tx: oneshot::Sender<Result<serde_json::Value, ClientError>>,
26 ) -> Self {
27 Self { params, tx }
28 }
29}
30
31#[must_use = "futures do nothing unless you `.await` or poll them"]
33#[pin_project]
34pub struct ResponseFuture<T> {
35 #[pin]
36 rx: oneshot::Receiver<Result<serde_json::Value, ClientError>>,
37 _marker: PhantomData<T>,
38}
39
40impl<T> ResponseFuture<T> {
41 pub(super) fn new(rx: oneshot::Receiver<Result<serde_json::Value, ClientError>>) -> Self {
42 Self {
43 rx,
44 _marker: PhantomData,
45 }
46 }
47}
48
49impl<T> Future for ResponseFuture<T>
50where
51 T: ServiceRequest,
52{
53 type Output = Result<T::Response, Error<T::Error>>;
54
55 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
56 let this = self.project();
57
58 let result = ready!(this.rx.poll(cx)).map_err(|_| ClientError::ChannelClosed)?;
59
60 let result = match result {
61 Ok(value) => serde_json::from_value(value).map_err(ClientError::Deserialization),
62
63 Err(err) => Err(err),
64 };
65
66 Poll::Ready(result.map_err(Into::into))
67 }
68}
69
70#[must_use = "futures do nothing unless you `.await` or poll them"]
73#[pin_project]
74pub struct EmptyResponseFuture<T> {
75 #[pin]
76 rx: ResponseFuture<T>,
77}
78
79impl<T> EmptyResponseFuture<T> {
80 pub(super) fn new(rx: ResponseFuture<T>) -> Self {
81 Self { rx }
82 }
83}
84
85impl<T> Future for EmptyResponseFuture<T>
86where
87 T: ServiceRequest,
88{
89 type Output = Result<(), Error<T::Error>>;
90
91 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
92 Poll::Ready(ready!(self.project().rx.poll(cx)).map(|_| ()))
93 }
94}
95
96pub fn create_request<T>(data: T) -> (OutboundRequest, ResponseFuture<T>)
100where
101 T: ServiceRequest,
102{
103 let (tx, rx) = oneshot::channel();
104
105 (
106 OutboundRequest::new(data.into_params(), tx),
107 ResponseFuture::new(rx),
108 )
109}