1use std::collections::HashMap;
8use std::future::Future;
9use std::pin::Pin;
10
11use std::sync::Arc;
12
13use serde::Serialize;
14
15use crate::error::Error;
16use crate::types::{Message, RequestId, Response};
17
18type BoxedHandler = Box<
20 dyn Fn(
21 serde_json::Value,
22 ) -> Pin<Box<dyn Future<Output = Result<serde_json::Value, Error>> + Send>>
23 + Send
24 + Sync,
25>;
26
27pub struct Methods {
49 handlers: HashMap<String, BoxedHandler>,
50}
51
52impl Methods {
53 pub fn new() -> Self {
55 Self {
56 handlers: HashMap::new(),
57 }
58 }
59
60 pub fn add<F, P, R, Fut>(mut self, method: &str, handler: F) -> Self
79 where
80 F: Fn(P) -> Fut + Send + Sync + 'static,
81 Fut: Future<Output = Result<R, Error>> + Send + Sync + 'static,
82 P: serde::de::DeserializeOwned + Send + Sync + 'static,
83 R: Serialize + Send + Sync + 'static,
84 {
85 let handler = Arc::new(handler);
86 let boxed: BoxedHandler = Box::new(move |params: serde_json::Value| {
87 let handler = Arc::clone(&handler);
88 Box::pin(async move {
89 let parsed: P = serde_json::from_value(params)?;
90 let result = handler(parsed).await?;
91 Ok(serde_json::to_value(result)?)
92 })
93 });
94
95 self.handlers.insert(method.to_string(), boxed);
96 self
97 }
98
99 pub(crate) fn get_handler(&self, method: &str) -> Option<&BoxedHandler> {
101 self.handlers.get(method)
102 }
103
104 pub async fn process_message(&self, json_str: &str) -> Option<String> {
114 let value: serde_json::Value = match serde_json::from_str(json_str) {
115 Ok(v) => v,
116 Err(_) => {
117 let error = crate::types::Error::parse_error("Parse error");
118 let response = Response::error(RequestId::Null, error);
119 match serde_json::to_string(&response) {
120 Ok(s) => return Some(s),
121 Err(e) => {
122 tracing::error!("Failed to serialize parse error response: {}", e);
123 return None;
124 }
125 }
126 }
127 };
128
129 let request_id = value.get("id").and_then(|id_value| match id_value {
130 serde_json::Value::Null => Some(RequestId::Null),
131 serde_json::Value::Number(n) => n.as_u64().map(RequestId::Number),
132 serde_json::Value::String(s) => Some(RequestId::String(s.clone())),
133 _ => None,
134 });
135
136 let message = match Message::from_json(value) {
137 Ok(msg) => msg,
138 Err(Error::InvalidRequest(_)) => {
139 let error = crate::types::Error::invalid_request("Invalid Request");
140 let id_to_use = request_id.unwrap_or(RequestId::Null);
141 let response = Response::error(id_to_use, error);
142 match serde_json::to_string(&response) {
143 Ok(s) => return Some(s),
144 Err(e) => {
145 tracing::error!("Failed to serialize invalid request response: {}", e);
146 return None;
147 }
148 }
149 }
150 Err(_) => {
151 let error = crate::types::Error::internal_error("Internal error");
152 let response = Response::error(request_id.unwrap_or(RequestId::Null), error);
153 match serde_json::to_string(&response) {
154 Ok(s) => return Some(s),
155 Err(e) => {
156 tracing::error!("Failed to serialize internal error response: {}", e);
157 return None;
158 }
159 }
160 }
161 };
162
163 match message {
164 Message::Request(request) => {
165 let method_name = &request.method;
166 let params = request.params.unwrap_or(serde_json::Value::Null);
167 let request_id = request.id.clone();
168 let response = if let Some(handler) = self.get_handler(method_name) {
169 let result = handler(params).await;
170 match result {
171 Ok(result_value) => Response::success(request_id, result_value),
172 Err(e) => {
173 let error = match e {
174 crate::error::Error::RpcError { code, message } => {
175 crate::types::Error::new(code, message, None)
176 }
177 _ => crate::types::Error::new(-32603, e.to_string(), None),
178 };
179 Response::error(request_id, error)
180 }
181 }
182 } else {
183 let error = crate::types::Error::method_not_found(format!(
184 "Unknown method: {}",
185 method_name
186 ));
187 Response::error(request_id, error)
188 };
189 match serde_json::to_string(&response) {
190 Ok(s) => Some(s),
191 Err(e) => {
192 tracing::error!("Failed to serialize response: {}", e);
193 None
194 }
195 }
196 }
197 Message::Notification(notification) => {
198 if let Some(handler) = self.get_handler(¬ification.method) {
199 let params = notification.params.unwrap_or(serde_json::Value::Null);
200 let _ = handler(params).await;
201 }
202 None
203 }
204 Message::Batch(messages) => {
205 let mut responses = Vec::new();
206
207 for message in messages {
208 match message {
209 Message::Request(request) => {
210 let method_name = &request.method;
211 let params = request.params.unwrap_or(serde_json::Value::Null);
212 let id = request.id;
213 let response = if let Some(handler) = self.get_handler(method_name) {
214 let result = handler(params).await;
215 match result {
216 Ok(result_value) => Response::success(id, result_value),
217 Err(e) => {
218 let error = match e {
219 crate::error::Error::RpcError { code, message } => {
220 crate::types::Error::new(code, message, None)
221 }
222 _ => crate::types::Error::new(
223 -32603,
224 e.to_string(),
225 None,
226 ),
227 };
228 Response::error(id, error)
229 }
230 }
231 } else {
232 let error = crate::types::Error::method_not_found(format!(
233 "Unknown method: {}",
234 method_name
235 ));
236 Response::error(id, error)
237 };
238 responses.push(response);
239 }
240 Message::Notification(notification) => {
241 if let Some(handler) = self.get_handler(¬ification.method) {
242 let params = notification.params.unwrap_or(serde_json::Value::Null);
243 let _ = handler(params).await;
244 }
245 }
246 Message::Response(response) => {
247 responses.push(response);
248 }
249 Message::Batch(_) => {
250 let error_response = Response::error(
251 crate::types::RequestId::Null,
252 crate::types::Error::invalid_request("Invalid Request"),
253 );
254 responses.push(error_response);
255 }
256 }
257 }
258
259 match serde_json::to_string(&responses) {
260 Ok(s) => Some(s),
261 Err(e) => {
262 tracing::error!("Failed to serialize batch responses: {}", e);
263 None
264 }
265 }
266 }
267 Message::Response(_response) => None,
268 }
269 }
270}
271
272impl Default for Methods {
273 fn default() -> Self {
274 Self::new()
275 }
276}