1use serde::{Deserialize, Deserializer, Serialize, Serializer};
7use serde_json::Value;
8use std::fmt;
9
10use crate::types::RequestId;
11
12pub const JSONRPC_VERSION: &str = "2.0";
14
15#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct JsonRpcVersion;
18
19impl Serialize for JsonRpcVersion {
20 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
21 where
22 S: Serializer,
23 {
24 serializer.serialize_str(JSONRPC_VERSION)
25 }
26}
27
28impl<'de> Deserialize<'de> for JsonRpcVersion {
29 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
30 where
31 D: Deserializer<'de>,
32 {
33 let version = String::deserialize(deserializer)?;
34 if version == JSONRPC_VERSION {
35 Ok(JsonRpcVersion)
36 } else {
37 Err(serde::de::Error::custom(format!(
38 "Invalid JSON-RPC version: expected '{JSONRPC_VERSION}', got '{version}'"
39 )))
40 }
41 }
42}
43
44#[derive(Debug, Clone, Serialize, Deserialize)]
46pub struct JsonRpcRequest {
47 pub jsonrpc: JsonRpcVersion,
49 pub method: String,
51 #[serde(skip_serializing_if = "Option::is_none")]
53 pub params: Option<Value>,
54 pub id: RequestId,
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize)]
60#[serde(untagged)]
61pub enum JsonRpcResponsePayload {
62 Success {
64 result: Value,
66 },
67 Error {
69 error: JsonRpcError,
71 },
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct JsonRpcResponse {
77 pub jsonrpc: JsonRpcVersion,
79 #[serde(flatten)]
81 pub payload: JsonRpcResponsePayload,
82 pub id: ResponseId,
84}
85
86#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
88#[serde(transparent)]
89pub struct ResponseId(pub Option<RequestId>);
90
91impl ResponseId {
92 pub fn from_request(id: RequestId) -> Self {
94 Self(Some(id))
95 }
96
97 pub fn null() -> Self {
99 Self(None)
100 }
101
102 pub fn as_request_id(&self) -> Option<&RequestId> {
104 self.0.as_ref()
105 }
106
107 pub fn is_null(&self) -> bool {
109 self.0.is_none()
110 }
111}
112
113#[derive(Debug, Clone, Serialize, Deserialize)]
115pub struct JsonRpcNotification {
116 pub jsonrpc: JsonRpcVersion,
118 pub method: String,
120 #[serde(skip_serializing_if = "Option::is_none")]
122 pub params: Option<Value>,
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize)]
127pub struct JsonRpcError {
128 pub code: i32,
130 pub message: String,
132 #[serde(skip_serializing_if = "Option::is_none")]
134 pub data: Option<Value>,
135}
136
137#[derive(Debug, Clone, Serialize, Deserialize)]
139#[serde(transparent)]
140pub struct JsonRpcBatch<T> {
141 pub items: Vec<T>,
143}
144
145#[derive(Debug, Clone, Copy, PartialEq, Eq)]
147pub enum JsonRpcErrorCode {
148 ParseError,
150 InvalidRequest,
152 MethodNotFound,
154 InvalidParams,
156 InternalError,
158 ApplicationError(i32),
160}
161
162impl JsonRpcErrorCode {
163 pub fn code(&self) -> i32 {
165 match self {
166 Self::ParseError => -32700,
167 Self::InvalidRequest => -32600,
168 Self::MethodNotFound => -32601,
169 Self::InvalidParams => -32602,
170 Self::InternalError => -32603,
171 Self::ApplicationError(code) => *code,
172 }
173 }
174
175 pub fn message(&self) -> &'static str {
177 match self {
178 Self::ParseError => "Parse error",
179 Self::InvalidRequest => "Invalid Request",
180 Self::MethodNotFound => "Method not found",
181 Self::InvalidParams => "Invalid params",
182 Self::InternalError => "Internal error",
183 Self::ApplicationError(_) => "Application error",
184 }
185 }
186}
187
188impl fmt::Display for JsonRpcErrorCode {
189 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
190 write!(f, "{} ({})", self.message(), self.code())
191 }
192}
193
194impl From<JsonRpcErrorCode> for JsonRpcError {
195 fn from(code: JsonRpcErrorCode) -> Self {
196 Self {
197 code: code.code(),
198 message: code.message().to_string(),
199 data: None,
200 }
201 }
202}
203
204impl From<i32> for JsonRpcErrorCode {
205 fn from(code: i32) -> Self {
206 match code {
207 -32700 => Self::ParseError,
208 -32600 => Self::InvalidRequest,
209 -32601 => Self::MethodNotFound,
210 -32602 => Self::InvalidParams,
211 -32603 => Self::InternalError,
212 other => Self::ApplicationError(other),
213 }
214 }
215}
216
217#[derive(Debug, Clone, Serialize, Deserialize)]
219#[serde(untagged)]
220pub enum JsonRpcMessage {
221 Request(JsonRpcRequest),
223 Response(JsonRpcResponse),
225 Notification(JsonRpcNotification),
227 RequestBatch(JsonRpcBatch<JsonRpcRequest>),
229 ResponseBatch(JsonRpcBatch<JsonRpcResponse>),
231 MessageBatch(JsonRpcBatch<JsonRpcMessage>),
233}
234
235impl JsonRpcRequest {
236 pub fn new(method: String, params: Option<Value>, id: RequestId) -> Self {
238 Self {
239 jsonrpc: JsonRpcVersion,
240 method,
241 params,
242 id,
243 }
244 }
245
246 pub fn without_params(method: String, id: RequestId) -> Self {
248 Self::new(method, None, id)
249 }
250
251 pub fn with_params<P: Serialize>(
253 method: String,
254 params: P,
255 id: RequestId,
256 ) -> Result<Self, serde_json::Error> {
257 let params_value = serde_json::to_value(params)?;
258 Ok(Self::new(method, Some(params_value), id))
259 }
260}
261
262impl JsonRpcResponse {
263 pub fn success(result: Value, id: RequestId) -> Self {
265 Self {
266 jsonrpc: JsonRpcVersion,
267 payload: JsonRpcResponsePayload::Success { result },
268 id: ResponseId::from_request(id),
269 }
270 }
271
272 pub fn error_response(error: JsonRpcError, id: RequestId) -> Self {
274 Self {
275 jsonrpc: JsonRpcVersion,
276 payload: JsonRpcResponsePayload::Error { error },
277 id: ResponseId::from_request(id),
278 }
279 }
280
281 pub fn parse_error(message: Option<String>) -> Self {
283 let error = JsonRpcError {
284 code: JsonRpcErrorCode::ParseError.code(),
285 message: message.unwrap_or_else(|| JsonRpcErrorCode::ParseError.message().to_string()),
286 data: None,
287 };
288 Self {
289 jsonrpc: JsonRpcVersion,
290 payload: JsonRpcResponsePayload::Error { error },
291 id: ResponseId::null(),
292 }
293 }
294
295 pub fn is_success(&self) -> bool {
297 matches!(self.payload, JsonRpcResponsePayload::Success { .. })
298 }
299
300 pub fn is_error(&self) -> bool {
302 matches!(self.payload, JsonRpcResponsePayload::Error { .. })
303 }
304
305 pub fn result(&self) -> Option<&Value> {
307 match &self.payload {
308 JsonRpcResponsePayload::Success { result } => Some(result),
309 JsonRpcResponsePayload::Error { .. } => None,
310 }
311 }
312
313 pub fn error(&self) -> Option<&JsonRpcError> {
315 match &self.payload {
316 JsonRpcResponsePayload::Success { .. } => None,
317 JsonRpcResponsePayload::Error { error } => Some(error),
318 }
319 }
320
321 pub fn request_id(&self) -> Option<&RequestId> {
323 self.id.as_request_id()
324 }
325
326 pub fn is_parse_error(&self) -> bool {
328 self.id.is_null()
329 }
330
331 pub fn result_mut(&mut self) -> Option<&mut Value> {
333 match &mut self.payload {
334 JsonRpcResponsePayload::Success { result } => Some(result),
335 JsonRpcResponsePayload::Error { .. } => None,
336 }
337 }
338
339 pub fn error_mut(&mut self) -> Option<&mut JsonRpcError> {
341 match &mut self.payload {
342 JsonRpcResponsePayload::Success { .. } => None,
343 JsonRpcResponsePayload::Error { error } => Some(error),
344 }
345 }
346
347 pub fn set_result(&mut self, result: Value) {
349 self.payload = JsonRpcResponsePayload::Success { result };
350 }
351
352 pub fn set_error(&mut self, error: JsonRpcError) {
354 self.payload = JsonRpcResponsePayload::Error { error };
355 }
356}
357
358impl JsonRpcNotification {
359 pub fn new(method: String, params: Option<Value>) -> Self {
361 Self {
362 jsonrpc: JsonRpcVersion,
363 method,
364 params,
365 }
366 }
367
368 pub fn without_params(method: String) -> Self {
370 Self::new(method, None)
371 }
372
373 pub fn with_params<P: Serialize>(method: String, params: P) -> Result<Self, serde_json::Error> {
375 let params_value = serde_json::to_value(params)?;
376 Ok(Self::new(method, Some(params_value)))
377 }
378}
379
380impl<T> JsonRpcBatch<T> {
381 pub fn new(items: Vec<T>) -> Self {
383 Self { items }
384 }
385
386 pub fn empty() -> Self {
388 Self::new(Vec::new())
389 }
390
391 pub fn push(&mut self, item: T) {
393 self.items.push(item);
394 }
395
396 pub fn len(&self) -> usize {
398 self.items.len()
399 }
400
401 pub fn is_empty(&self) -> bool {
403 self.items.is_empty()
404 }
405
406 pub fn iter(&self) -> impl Iterator<Item = &T> {
408 self.items.iter()
409 }
410}
411
412impl<T> IntoIterator for JsonRpcBatch<T> {
413 type Item = T;
414 type IntoIter = std::vec::IntoIter<T>;
415
416 fn into_iter(self) -> Self::IntoIter {
417 self.items.into_iter()
418 }
419}
420
421impl<T> From<Vec<T>> for JsonRpcBatch<T> {
422 fn from(items: Vec<T>) -> Self {
423 Self::new(items)
424 }
425}
426
427pub mod utils {
429 use super::*;
430
431 pub fn parse_message(json: &str) -> Result<JsonRpcMessage, serde_json::Error> {
433 serde_json::from_str(json)
434 }
435
436 pub fn serialize_message(message: &JsonRpcMessage) -> Result<String, serde_json::Error> {
438 serde_json::to_string(message)
439 }
440
441 pub fn is_batch(json: &str) -> bool {
443 json.trim_start().starts_with('[')
444 }
445
446 pub fn extract_method(json: &str) -> Option<String> {
448 if let Ok(value) = serde_json::from_str::<serde_json::Value>(json)
450 && let Some(method) = value.get("method")
451 {
452 return method.as_str().map(String::from);
453 }
454 None
455 }
456}
457
458#[cfg(test)]
459mod tests {
460 use super::*;
461 use serde_json::json;
462
463 #[test]
464 fn test_jsonrpc_version() {
465 let version = JsonRpcVersion;
466 let json = serde_json::to_string(&version).unwrap();
467 assert_eq!(json, "\"2.0\"");
468
469 let parsed: JsonRpcVersion = serde_json::from_str(&json).unwrap();
470 assert_eq!(parsed, version);
471 }
472
473 #[test]
474 fn test_request_creation() {
475 let request = JsonRpcRequest::new(
476 "test_method".to_string(),
477 Some(json!({"key": "value"})),
478 RequestId::String("test-id".to_string()),
479 );
480
481 assert_eq!(request.method, "test_method");
482 assert!(request.params.is_some());
483 }
484
485 #[test]
486 fn test_response_creation() {
487 let response = JsonRpcResponse::success(
488 json!({"result": "success"}),
489 RequestId::String("test-id".to_string()),
490 );
491
492 assert!(response.is_success());
493 assert!(!response.is_error());
494 assert!(response.result().is_some());
495 assert!(response.error().is_none());
496 assert!(!response.is_parse_error());
497 }
498
499 #[test]
500 fn test_error_response() {
501 let error = JsonRpcError::from(JsonRpcErrorCode::MethodNotFound);
502 let response =
503 JsonRpcResponse::error_response(error, RequestId::String("test-id".to_string()));
504
505 assert!(!response.is_success());
506 assert!(response.is_error());
507 assert!(response.result().is_none());
508 assert!(response.error().is_some());
509 assert!(!response.is_parse_error());
510 }
511
512 #[test]
513 fn test_parse_error_response() {
514 let response = JsonRpcResponse::parse_error(Some("Invalid JSON".to_string()));
515
516 assert!(!response.is_success());
517 assert!(response.is_error());
518 assert!(response.result().is_none());
519 assert!(response.error().is_some());
520 assert!(response.is_parse_error());
521 assert!(response.request_id().is_none());
522
523 let error = response.error().unwrap();
525 assert_eq!(error.code, JsonRpcErrorCode::ParseError.code());
526 assert_eq!(error.message, "Invalid JSON");
527 }
528
529 #[test]
530 fn test_notification() {
531 let notification = JsonRpcNotification::without_params("test_notification".to_string());
532 assert_eq!(notification.method, "test_notification");
533 assert!(notification.params.is_none());
534 }
535
536 #[test]
537 fn test_batch() {
538 let mut batch = JsonRpcBatch::<JsonRpcRequest>::empty();
539 assert!(batch.is_empty());
540
541 batch.push(JsonRpcRequest::without_params(
542 "method1".to_string(),
543 RequestId::String("1".to_string()),
544 ));
545 batch.push(JsonRpcRequest::without_params(
546 "method2".to_string(),
547 RequestId::String("2".to_string()),
548 ));
549
550 assert_eq!(batch.len(), 2);
551 assert!(!batch.is_empty());
552 }
553
554 #[test]
555 fn test_serialization() {
556 let request = JsonRpcRequest::new(
557 "test_method".to_string(),
558 Some(json!({"param": "value"})),
559 RequestId::String("123".to_string()),
560 );
561
562 let json = serde_json::to_string(&request).unwrap();
563 let parsed: JsonRpcRequest = serde_json::from_str(&json).unwrap();
564
565 assert_eq!(parsed.method, request.method);
566 assert_eq!(parsed.params, request.params);
567 }
568
569 #[test]
570 fn test_utils() {
571 let json = r#"{"jsonrpc":"2.0","method":"test","id":"123"}"#;
572
573 assert!(!utils::is_batch(json));
574 assert_eq!(utils::extract_method(json), Some("test".to_string()));
575
576 let batch_json = r#"[{"jsonrpc":"2.0","method":"test","id":"123"}]"#;
577 assert!(utils::is_batch(batch_json));
578 }
579
580 #[test]
581 fn test_error_codes() {
582 let parse_error = JsonRpcErrorCode::ParseError;
583 assert_eq!(parse_error.code(), -32700);
584 assert_eq!(parse_error.message(), "Parse error");
585
586 let app_error = JsonRpcErrorCode::ApplicationError(-32001);
587 assert_eq!(app_error.code(), -32001);
588 }
589}