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", default)]
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", default)]
122 pub params: Option<Value>,
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
127pub struct JsonRpcError {
128 pub code: i32,
130 pub message: String,
132 #[serde(skip_serializing_if = "Option::is_none", default)]
134 pub data: Option<Value>,
135}
136
137impl JsonRpcError {
138 pub fn new(code: i32, message: impl Into<String>) -> Self {
140 Self {
141 code,
142 message: message.into(),
143 data: None,
144 }
145 }
146
147 pub fn with_data(code: i32, message: impl Into<String>, data: Value) -> Self {
149 Self {
150 code,
151 message: message.into(),
152 data: Some(data),
153 }
154 }
155
156 pub fn parse_error() -> Self {
158 Self::new(-32700, "Parse error")
159 }
160
161 pub fn parse_error_with_details(details: impl Into<String>) -> Self {
163 Self::with_data(
164 -32700,
165 "Parse error",
166 serde_json::json!({ "details": details.into() }),
167 )
168 }
169
170 pub fn invalid_request() -> Self {
172 Self::new(-32600, "Invalid Request")
173 }
174
175 pub fn invalid_request_with_reason(reason: impl Into<String>) -> Self {
177 Self::with_data(
178 -32600,
179 "Invalid Request",
180 serde_json::json!({ "reason": reason.into() }),
181 )
182 }
183
184 pub fn method_not_found(method: &str) -> Self {
186 Self::new(-32601, format!("Method not found: {method}"))
187 }
188
189 pub fn invalid_params(details: &str) -> Self {
191 Self::new(-32602, format!("Invalid params: {details}"))
192 }
193
194 pub fn internal_error(details: &str) -> Self {
196 Self::new(-32603, format!("Internal error: {details}"))
197 }
198
199 pub fn is_parse_error(&self) -> bool {
201 self.code == -32700
202 }
203
204 pub fn is_invalid_request(&self) -> bool {
206 self.code == -32600
207 }
208
209 pub fn code(&self) -> i32 {
211 self.code
212 }
213}
214
215#[derive(Debug, Clone, Copy, PartialEq, Eq)]
217pub enum JsonRpcErrorCode {
218 ParseError,
220 InvalidRequest,
222 MethodNotFound,
224 InvalidParams,
226 InternalError,
228 ApplicationError(i32),
230}
231
232impl JsonRpcErrorCode {
233 pub fn code(&self) -> i32 {
235 match self {
236 Self::ParseError => -32700,
237 Self::InvalidRequest => -32600,
238 Self::MethodNotFound => -32601,
239 Self::InvalidParams => -32602,
240 Self::InternalError => -32603,
241 Self::ApplicationError(code) => *code,
242 }
243 }
244
245 pub fn message(&self) -> &'static str {
247 match self {
248 Self::ParseError => "Parse error",
249 Self::InvalidRequest => "Invalid Request",
250 Self::MethodNotFound => "Method not found",
251 Self::InvalidParams => "Invalid params",
252 Self::InternalError => "Internal error",
253 Self::ApplicationError(_) => "Application error",
254 }
255 }
256}
257
258impl fmt::Display for JsonRpcErrorCode {
259 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
260 write!(f, "{} ({})", self.message(), self.code())
261 }
262}
263
264impl From<JsonRpcErrorCode> for JsonRpcError {
265 fn from(code: JsonRpcErrorCode) -> Self {
266 Self {
267 code: code.code(),
268 message: code.message().to_string(),
269 data: None,
270 }
271 }
272}
273
274impl From<i32> for JsonRpcErrorCode {
275 fn from(code: i32) -> Self {
276 match code {
277 -32700 => Self::ParseError,
278 -32600 => Self::InvalidRequest,
279 -32601 => Self::MethodNotFound,
280 -32602 => Self::InvalidParams,
281 -32603 => Self::InternalError,
282 other => Self::ApplicationError(other),
283 }
284 }
285}
286
287#[derive(Debug, Clone, Serialize, Deserialize)]
291#[serde(untagged)]
292pub enum JsonRpcMessage {
293 Request(JsonRpcRequest),
295 Response(JsonRpcResponse),
297 Notification(JsonRpcNotification),
299}
300
301impl JsonRpcRequest {
302 pub fn new(method: String, params: Option<Value>, id: RequestId) -> Self {
304 Self {
305 jsonrpc: JsonRpcVersion,
306 method,
307 params,
308 id,
309 }
310 }
311
312 pub fn without_params(method: String, id: RequestId) -> Self {
314 Self::new(method, None, id)
315 }
316
317 pub fn with_params<P: Serialize>(
319 method: String,
320 params: P,
321 id: RequestId,
322 ) -> Result<Self, serde_json::Error> {
323 let params_value = serde_json::to_value(params)?;
324 Ok(Self::new(method, Some(params_value), id))
325 }
326}
327
328impl JsonRpcResponse {
329 pub fn success(result: Value, id: RequestId) -> Self {
331 Self {
332 jsonrpc: JsonRpcVersion,
333 payload: JsonRpcResponsePayload::Success { result },
334 id: ResponseId::from_request(id),
335 }
336 }
337
338 pub fn error_response(error: JsonRpcError, id: RequestId) -> Self {
340 Self {
341 jsonrpc: JsonRpcVersion,
342 payload: JsonRpcResponsePayload::Error { error },
343 id: ResponseId::from_request(id),
344 }
345 }
346
347 pub fn parse_error(message: Option<String>) -> Self {
349 let error = JsonRpcError {
350 code: JsonRpcErrorCode::ParseError.code(),
351 message: message.unwrap_or_else(|| JsonRpcErrorCode::ParseError.message().to_string()),
352 data: None,
353 };
354 Self {
355 jsonrpc: JsonRpcVersion,
356 payload: JsonRpcResponsePayload::Error { error },
357 id: ResponseId::null(),
358 }
359 }
360
361 pub fn is_success(&self) -> bool {
363 matches!(self.payload, JsonRpcResponsePayload::Success { .. })
364 }
365
366 pub fn is_error(&self) -> bool {
368 matches!(self.payload, JsonRpcResponsePayload::Error { .. })
369 }
370
371 pub fn result(&self) -> Option<&Value> {
373 match &self.payload {
374 JsonRpcResponsePayload::Success { result } => Some(result),
375 JsonRpcResponsePayload::Error { .. } => None,
376 }
377 }
378
379 pub fn error(&self) -> Option<&JsonRpcError> {
381 match &self.payload {
382 JsonRpcResponsePayload::Success { .. } => None,
383 JsonRpcResponsePayload::Error { error } => Some(error),
384 }
385 }
386
387 pub fn request_id(&self) -> Option<&RequestId> {
389 self.id.as_request_id()
390 }
391
392 pub fn is_parse_error(&self) -> bool {
394 self.id.is_null()
395 }
396
397 pub fn result_mut(&mut self) -> Option<&mut Value> {
399 match &mut self.payload {
400 JsonRpcResponsePayload::Success { result } => Some(result),
401 JsonRpcResponsePayload::Error { .. } => None,
402 }
403 }
404
405 pub fn error_mut(&mut self) -> Option<&mut JsonRpcError> {
407 match &mut self.payload {
408 JsonRpcResponsePayload::Success { .. } => None,
409 JsonRpcResponsePayload::Error { error } => Some(error),
410 }
411 }
412
413 pub fn set_result(&mut self, result: Value) {
415 self.payload = JsonRpcResponsePayload::Success { result };
416 }
417
418 pub fn set_error(&mut self, error: JsonRpcError) {
420 self.payload = JsonRpcResponsePayload::Error { error };
421 }
422}
423
424impl JsonRpcNotification {
425 pub fn new(method: String, params: Option<Value>) -> Self {
427 Self {
428 jsonrpc: JsonRpcVersion,
429 method,
430 params,
431 }
432 }
433
434 pub fn without_params(method: String) -> Self {
436 Self::new(method, None)
437 }
438
439 pub fn with_params<P: Serialize>(method: String, params: P) -> Result<Self, serde_json::Error> {
441 let params_value = serde_json::to_value(params)?;
442 Ok(Self::new(method, Some(params_value)))
443 }
444}
445
446pub mod utils {
448 use super::*;
449
450 pub fn parse_message(json: &str) -> Result<JsonRpcMessage, serde_json::Error> {
452 serde_json::from_str(json)
453 }
454
455 pub fn serialize_message(message: &JsonRpcMessage) -> Result<String, serde_json::Error> {
457 serde_json::to_string(message)
458 }
459
460 pub fn extract_method(json: &str) -> Option<String> {
462 if let Ok(value) = serde_json::from_str::<serde_json::Value>(json)
464 && let Some(method) = value.get("method")
465 {
466 return method.as_str().map(String::from);
467 }
468 None
469 }
470}
471
472pub mod http {
494 use serde::{Deserialize, Serialize};
495 use serde_json::Value;
496
497 #[derive(Debug, Clone, Serialize, Deserialize)]
502 pub struct HttpJsonRpcRequest {
503 pub jsonrpc: String,
505 #[serde(default)]
507 pub id: Option<Value>,
508 pub method: String,
510 #[serde(default)]
512 pub params: Option<Value>,
513 }
514
515 impl HttpJsonRpcRequest {
516 pub fn is_valid(&self) -> bool {
518 self.jsonrpc == "2.0" && !self.method.is_empty()
519 }
520
521 pub fn is_notification(&self) -> bool {
523 self.id.is_none()
524 }
525
526 pub fn id_string(&self) -> Option<String> {
528 self.id.as_ref().map(|v| match v {
529 Value::String(s) => s.clone(),
530 Value::Number(n) => n.to_string(),
531 _ => v.to_string(),
532 })
533 }
534 }
535
536 #[derive(Debug, Clone, Serialize, Deserialize)]
541 pub struct HttpJsonRpcResponse {
542 pub jsonrpc: String,
544 #[serde(default)]
546 pub id: Option<Value>,
547 #[serde(skip_serializing_if = "Option::is_none")]
549 pub result: Option<Value>,
550 #[serde(skip_serializing_if = "Option::is_none")]
552 pub error: Option<super::JsonRpcError>,
553 }
554
555 impl HttpJsonRpcResponse {
556 pub fn success(id: Option<Value>, result: Value) -> Self {
558 Self {
559 jsonrpc: "2.0".to_string(),
560 id,
561 result: Some(result),
562 error: None,
563 }
564 }
565
566 pub fn error(id: Option<Value>, error: super::JsonRpcError) -> Self {
568 Self {
569 jsonrpc: "2.0".to_string(),
570 id,
571 result: None,
572 error: Some(error),
573 }
574 }
575
576 pub fn error_from_code(id: Option<Value>, code: i32, message: impl Into<String>) -> Self {
578 Self::error(id, super::JsonRpcError::new(code, message))
579 }
580
581 pub fn invalid_request(id: Option<Value>, reason: impl Into<String>) -> Self {
583 Self::error(id, super::JsonRpcError::invalid_request_with_reason(reason))
584 }
585
586 pub fn parse_error(details: Option<String>) -> Self {
588 Self::error(
589 None,
590 details
591 .map(super::JsonRpcError::parse_error_with_details)
592 .unwrap_or_else(super::JsonRpcError::parse_error),
593 )
594 }
595
596 pub fn internal_error(id: Option<Value>, details: &str) -> Self {
598 Self::error(id, super::JsonRpcError::internal_error(details))
599 }
600
601 pub fn method_not_found(id: Option<Value>, method: &str) -> Self {
603 Self::error(id, super::JsonRpcError::method_not_found(method))
604 }
605
606 pub fn is_error(&self) -> bool {
608 self.error.is_some()
609 }
610
611 pub fn is_success(&self) -> bool {
613 self.result.is_some() && self.error.is_none()
614 }
615 }
616
617 #[cfg(test)]
618 mod tests {
619 use super::*;
620
621 #[test]
622 fn test_http_request_parsing() {
623 let json = r#"{"jsonrpc":"2.0","method":"test","id":1,"params":{"key":"value"}}"#;
624 let request: HttpJsonRpcRequest = serde_json::from_str(json).unwrap();
625 assert!(request.is_valid());
626 assert!(!request.is_notification());
627 assert_eq!(request.method, "test");
628 }
629
630 #[test]
631 fn test_http_request_invalid_version() {
632 let json = r#"{"jsonrpc":"1.0","method":"test","id":1}"#;
633 let request: HttpJsonRpcRequest = serde_json::from_str(json).unwrap();
634 assert!(!request.is_valid());
635 }
636
637 #[test]
638 fn test_http_response_success() {
639 let response = HttpJsonRpcResponse::success(
640 Some(Value::Number(1.into())),
641 serde_json::json!({"result": "ok"}),
642 );
643 assert!(response.is_success());
644 assert!(!response.is_error());
645 }
646
647 #[test]
648 fn test_http_response_error() {
649 let response = HttpJsonRpcResponse::invalid_request(
650 Some(Value::String("req-1".into())),
651 "jsonrpc must be 2.0",
652 );
653 assert!(!response.is_success());
654 assert!(response.is_error());
655 }
656
657 #[test]
658 fn test_http_response_serialization() {
659 let response = HttpJsonRpcResponse::success(
660 Some(Value::Number(1.into())),
661 serde_json::json!({"data": "test"}),
662 );
663 let json = serde_json::to_string(&response).unwrap();
664 assert!(json.contains(r#""jsonrpc":"2.0""#));
665 assert!(json.contains(r#""result""#));
666 assert!(!json.contains(r#""error""#));
667 }
668 }
669}
670
671#[cfg(test)]
672#[allow(deprecated)] mod tests {
674 use super::*;
675 use serde_json::json;
676
677 #[test]
678 fn test_jsonrpc_version() {
679 let version = JsonRpcVersion;
680 let json = serde_json::to_string(&version).unwrap();
681 assert_eq!(json, "\"2.0\"");
682
683 let parsed: JsonRpcVersion = serde_json::from_str(&json).unwrap();
684 assert_eq!(parsed, version);
685 }
686
687 #[test]
688 fn test_request_creation() {
689 let request = JsonRpcRequest::new(
690 "test_method".to_string(),
691 Some(json!({"key": "value"})),
692 RequestId::String("test-id".to_string()),
693 );
694
695 assert_eq!(request.method, "test_method");
696 assert!(request.params.is_some());
697 }
698
699 #[test]
700 fn test_response_creation() {
701 let response = JsonRpcResponse::success(
702 json!({"result": "success"}),
703 RequestId::String("test-id".to_string()),
704 );
705
706 assert!(response.is_success());
707 assert!(!response.is_error());
708 assert!(response.result().is_some());
709 assert!(response.error().is_none());
710 assert!(!response.is_parse_error());
711 }
712
713 #[test]
714 fn test_error_response() {
715 let error = JsonRpcError::from(JsonRpcErrorCode::MethodNotFound);
716 let response =
717 JsonRpcResponse::error_response(error, RequestId::String("test-id".to_string()));
718
719 assert!(!response.is_success());
720 assert!(response.is_error());
721 assert!(response.result().is_none());
722 assert!(response.error().is_some());
723 assert!(!response.is_parse_error());
724 }
725
726 #[test]
727 fn test_parse_error_response() {
728 let response = JsonRpcResponse::parse_error(Some("Invalid JSON".to_string()));
729
730 assert!(!response.is_success());
731 assert!(response.is_error());
732 assert!(response.result().is_none());
733 assert!(response.error().is_some());
734 assert!(response.is_parse_error());
735 assert!(response.request_id().is_none());
736
737 let error = response.error().unwrap();
739 assert_eq!(error.code, JsonRpcErrorCode::ParseError.code());
740 assert_eq!(error.message, "Invalid JSON");
741 }
742
743 #[test]
744 fn test_notification() {
745 let notification = JsonRpcNotification::without_params("test_notification".to_string());
746 assert_eq!(notification.method, "test_notification");
747 assert!(notification.params.is_none());
748 }
749
750 #[test]
751 fn test_serialization() {
752 let request = JsonRpcRequest::new(
753 "test_method".to_string(),
754 Some(json!({"param": "value"})),
755 RequestId::String("123".to_string()),
756 );
757
758 let json = serde_json::to_string(&request).unwrap();
759 let parsed: JsonRpcRequest = serde_json::from_str(&json).unwrap();
760
761 assert_eq!(parsed.method, request.method);
762 assert_eq!(parsed.params, request.params);
763 }
764
765 #[test]
766 fn test_utils() {
767 let json = r#"{"jsonrpc":"2.0","method":"test","id":"123"}"#;
768 assert_eq!(utils::extract_method(json), Some("test".to_string()));
769 }
770
771 #[test]
772 fn test_error_codes() {
773 let parse_error = JsonRpcErrorCode::ParseError;
774 assert_eq!(parse_error.code(), -32700);
775 assert_eq!(parse_error.message(), "Parse error");
776
777 let app_error = JsonRpcErrorCode::ApplicationError(-32001);
778 assert_eq!(app_error.code(), -32001);
779 }
780}