workflow_rpc/server/interface/
method.rs1use crate::imports::*;
3
4#[async_trait]
8pub(crate) trait MethodTrait<ServerContext, ConnectionContext>:
9 Send + Sync + 'static
10{
11 async fn call_with_borsh(
12 &self,
13 server_ctx: ServerContext,
14 connection_ctx: ConnectionContext,
15 data: &[u8],
16 ) -> ServerResult<Vec<u8>>;
17 async fn call_with_serde_json(
18 &self,
19 server_ctx: ServerContext,
20 connection_ctx: ConnectionContext,
21 value: Value,
22 ) -> ServerResult<Value>;
23}
24
25pub type MethodFn<ServerContext, ConnectionContext, Req, Resp> = Arc<
27 Box<
28 dyn Send
29 + Sync
30 + Fn(ServerContext, ConnectionContext, Req) -> MethodFnReturn<Resp>
31 + 'static,
32 >,
33>;
34
35pub type MethodFnReturn<T> = Pin<Box<(dyn Send + 'static + Future<Output = ServerResult<T>>)>>;
37
38pub struct Method<ServerContext, ConnectionContext, Req, Resp>
40where
41 ServerContext: Send + Sync + 'static,
42 Req: MsgT,
43 Resp: MsgT,
44{
45 method: MethodFn<ServerContext, ConnectionContext, Req, Resp>,
46}
47
48impl<ServerContext, ConnectionContext, Req, Resp>
49 Method<ServerContext, ConnectionContext, Req, Resp>
50where
51 ServerContext: Send + Sync + 'static,
52 Req: MsgT,
53 Resp: MsgT,
54{
55 pub fn new<FN>(method_fn: FN) -> Method<ServerContext, ConnectionContext, Req, Resp>
56 where
57 FN: Send
58 + Sync
59 + Fn(ServerContext, ConnectionContext, Req) -> MethodFnReturn<Resp>
60 + 'static,
61 {
62 Method {
63 method: Arc::new(Box::new(method_fn)),
64 }
65 }
66}
67
68#[async_trait]
69impl<ServerContext, ConnectionContext, Req, Resp> MethodTrait<ServerContext, ConnectionContext>
70 for Method<ServerContext, ConnectionContext, Req, Resp>
71where
72 ServerContext: Clone + Send + Sync + 'static,
73 ConnectionContext: Clone + Send + Sync + 'static,
74 Req: MsgT,
75 Resp: MsgT,
76{
77 async fn call_with_borsh(
78 &self,
79 server_ctx: ServerContext,
80 connection_ctx: ConnectionContext,
81 data: &[u8],
82 ) -> ServerResult<Vec<u8>> {
83 let req = Req::try_from_slice(data)?;
84 let resp = (self.method)(server_ctx, connection_ctx, req).await;
85 let vec = borsh::to_vec(&resp)?;
86 Ok(vec)
87 }
88
89 async fn call_with_serde_json(
90 &self,
91 server_ctx: ServerContext,
92 connection_ctx: ConnectionContext,
93 value: Value,
94 ) -> ServerResult<Value> {
95 let req: Req = serde_json::from_value(value).map_err(|_| ServerError::ReqDeserialize)?;
96 let resp = (self.method)(server_ctx, connection_ctx, req).await?;
97 Ok(serde_json::to_value(resp).map_err(|_| ServerError::RespSerialize)?)
98 }
99}