turul_rpc_server/
handler.rs1use async_trait::async_trait;
2use serde_json::Value;
3
4use turul_rpc_core::error::JsonRpcErrorObject;
5use turul_rpc_core::request::RequestParams;
6
7use crate::session::SessionContext;
8
9#[async_trait]
14pub trait JsonRpcHandler: Send + Sync {
15 type Error: std::error::Error + Send + Sync + 'static;
17
18 async fn handle(
22 &self,
23 method: &str,
24 params: Option<RequestParams>,
25 session_context: Option<SessionContext>,
26 ) -> Result<Value, Self::Error>;
27
28 async fn handle_notification(
31 &self,
32 method: &str,
33 params: Option<RequestParams>,
34 session_context: Option<SessionContext>,
35 ) -> Result<(), Self::Error> {
36 let _ = (method, params, session_context);
37 Ok(())
38 }
39
40 fn supported_methods(&self) -> Vec<String> {
42 vec![]
43 }
44}
45
46pub struct FunctionHandler<F, N, E>
48where
49 E: std::error::Error + Send + Sync + 'static,
50 F: Fn(
51 &str,
52 Option<RequestParams>,
53 Option<SessionContext>,
54 ) -> futures::future::BoxFuture<'static, Result<Value, E>>
55 + Send
56 + Sync,
57 N: Fn(
58 &str,
59 Option<RequestParams>,
60 Option<SessionContext>,
61 ) -> futures::future::BoxFuture<'static, Result<(), E>>
62 + Send
63 + Sync,
64{
65 handler_fn: F,
66 notification_fn: Option<N>,
67 methods: Vec<String>,
68}
69
70impl<F, N, E> FunctionHandler<F, N, E>
71where
72 E: std::error::Error + Send + Sync + 'static,
73 F: Fn(
74 &str,
75 Option<RequestParams>,
76 Option<SessionContext>,
77 ) -> futures::future::BoxFuture<'static, Result<Value, E>>
78 + Send
79 + Sync,
80 N: Fn(
81 &str,
82 Option<RequestParams>,
83 Option<SessionContext>,
84 ) -> futures::future::BoxFuture<'static, Result<(), E>>
85 + Send
86 + Sync,
87{
88 pub fn new(handler_fn: F) -> Self {
89 Self {
90 handler_fn,
91 notification_fn: None,
92 methods: vec![],
93 }
94 }
95
96 pub fn with_notification_handler(mut self, notification_fn: N) -> Self {
97 self.notification_fn = Some(notification_fn);
98 self
99 }
100
101 pub fn with_methods(mut self, methods: Vec<String>) -> Self {
102 self.methods = methods;
103 self
104 }
105}
106
107#[async_trait]
108impl<F, N, E> JsonRpcHandler for FunctionHandler<F, N, E>
109where
110 E: std::error::Error + Send + Sync + 'static,
111 F: Fn(
112 &str,
113 Option<RequestParams>,
114 Option<SessionContext>,
115 ) -> futures::future::BoxFuture<'static, Result<Value, E>>
116 + Send
117 + Sync,
118 N: Fn(
119 &str,
120 Option<RequestParams>,
121 Option<SessionContext>,
122 ) -> futures::future::BoxFuture<'static, Result<(), E>>
123 + Send
124 + Sync,
125{
126 type Error = E;
127
128 async fn handle(
129 &self,
130 method: &str,
131 params: Option<RequestParams>,
132 session_context: Option<SessionContext>,
133 ) -> Result<Value, Self::Error> {
134 (self.handler_fn)(method, params, session_context).await
135 }
136
137 async fn handle_notification(
138 &self,
139 method: &str,
140 params: Option<RequestParams>,
141 session_context: Option<SessionContext>,
142 ) -> Result<(), Self::Error> {
143 if let Some(ref notification_fn) = self.notification_fn {
144 (notification_fn)(method, params, session_context).await
145 } else {
146 Ok(())
147 }
148 }
149
150 fn supported_methods(&self) -> Vec<String> {
151 self.methods.clone()
152 }
153}
154
155pub trait ToJsonRpcError: std::error::Error + Send + Sync + 'static {
160 fn to_error_object(&self) -> JsonRpcErrorObject;
162}