Skip to main content

turbomcp_protocol/
jsonrpc.rs

1//! # JSON-RPC 2.0 Implementation
2//!
3//! This module provides a complete implementation of JSON-RPC 2.0 protocol
4//! with support for batching, streaming, and MCP-specific extensions.
5
6use serde::{Deserialize, Deserializer, Serialize, Serializer};
7use serde_json::Value;
8use std::fmt;
9
10use crate::types::RequestId;
11
12/// JSON-RPC version constant
13pub const JSONRPC_VERSION: &str = "2.0";
14
15/// JSON-RPC version type
16#[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/// JSON-RPC request message
45#[derive(Debug, Clone, Serialize, Deserialize)]
46pub struct JsonRpcRequest {
47    /// JSON-RPC version
48    pub jsonrpc: JsonRpcVersion,
49    /// Request method name
50    pub method: String,
51    /// Request parameters
52    #[serde(skip_serializing_if = "Option::is_none", default)]
53    pub params: Option<Value>,
54    /// Request identifier
55    pub id: RequestId,
56}
57
58/// JSON-RPC response payload - ensures mutual exclusion of result and error
59#[derive(Debug, Clone, Serialize, Deserialize)]
60#[serde(untagged)]
61pub enum JsonRpcResponsePayload {
62    /// Successful response with result
63    Success {
64        /// Response result
65        result: Value,
66    },
67    /// Error response
68    Error {
69        /// Response error
70        error: JsonRpcError,
71    },
72}
73
74/// JSON-RPC response message
75#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct JsonRpcResponse {
77    /// JSON-RPC version
78    pub jsonrpc: JsonRpcVersion,
79    /// Response payload (either result or error, never both)
80    #[serde(flatten)]
81    pub payload: JsonRpcResponsePayload,
82    /// Request identifier (required except for parse errors)
83    pub id: ResponseId,
84}
85
86/// Response ID - handles the special case where parse errors have null ID
87#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
88#[serde(transparent)]
89pub struct ResponseId(pub Option<RequestId>);
90
91impl ResponseId {
92    /// Create a response ID for a normal response
93    pub fn from_request(id: RequestId) -> Self {
94        Self(Some(id))
95    }
96
97    /// Create a null response ID for parse errors
98    pub fn null() -> Self {
99        Self(None)
100    }
101
102    /// Get the request ID if present
103    pub fn as_request_id(&self) -> Option<&RequestId> {
104        self.0.as_ref()
105    }
106
107    /// Check if this is a null ID (parse error)
108    pub fn is_null(&self) -> bool {
109        self.0.is_none()
110    }
111}
112
113/// JSON-RPC notification message (no response expected)
114#[derive(Debug, Clone, Serialize, Deserialize)]
115pub struct JsonRpcNotification {
116    /// JSON-RPC version
117    pub jsonrpc: JsonRpcVersion,
118    /// Notification method name
119    pub method: String,
120    /// Notification parameters
121    #[serde(skip_serializing_if = "Option::is_none", default)]
122    pub params: Option<Value>,
123}
124
125/// JSON-RPC error object
126#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
127pub struct JsonRpcError {
128    /// Error code
129    pub code: i32,
130    /// Error message
131    pub message: String,
132    /// Additional error data
133    #[serde(skip_serializing_if = "Option::is_none", default)]
134    pub data: Option<Value>,
135}
136
137impl JsonRpcError {
138    /// Create a new JSON-RPC error
139    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    /// Create a new JSON-RPC error with additional data
148    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    /// Create a parse error (-32700)
157    pub fn parse_error() -> Self {
158        Self::new(-32700, "Parse error")
159    }
160
161    /// Create a parse error with details
162    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    /// Create an invalid request error (-32600)
171    pub fn invalid_request() -> Self {
172        Self::new(-32600, "Invalid Request")
173    }
174
175    /// Create an invalid request error with reason
176    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    /// Create a method not found error (-32601)
185    pub fn method_not_found(method: &str) -> Self {
186        Self::new(-32601, format!("Method not found: {method}"))
187    }
188
189    /// Create an invalid params error (-32602)
190    pub fn invalid_params(details: &str) -> Self {
191        Self::new(-32602, format!("Invalid params: {details}"))
192    }
193
194    /// Create an internal error (-32603)
195    pub fn internal_error(details: &str) -> Self {
196        Self::new(-32603, format!("Internal error: {details}"))
197    }
198
199    /// Check if this is a parse error
200    pub fn is_parse_error(&self) -> bool {
201        self.code == -32700
202    }
203
204    /// Check if this is an invalid request error
205    pub fn is_invalid_request(&self) -> bool {
206        self.code == -32600
207    }
208
209    /// Get the error code
210    pub fn code(&self) -> i32 {
211        self.code
212    }
213}
214
215/// Standard JSON-RPC error codes
216#[derive(Debug, Clone, Copy, PartialEq, Eq)]
217pub enum JsonRpcErrorCode {
218    /// Parse error (-32700)
219    ParseError,
220    /// Invalid request (-32600)
221    InvalidRequest,
222    /// Method not found (-32601)
223    MethodNotFound,
224    /// Invalid params (-32602)
225    InvalidParams,
226    /// Internal error (-32603)
227    InternalError,
228    /// Application-defined error
229    ApplicationError(i32),
230}
231
232impl JsonRpcErrorCode {
233    /// Get the numeric error code
234    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    /// Get the standard error message
246    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/// JSON-RPC message type (union of request, response, notification)
288///
289/// Per MCP 2025-06-18 specification, batch operations are not supported.
290#[derive(Debug, Clone, Serialize, Deserialize)]
291#[serde(untagged)]
292pub enum JsonRpcMessage {
293    /// Request message
294    Request(JsonRpcRequest),
295    /// Response message
296    Response(JsonRpcResponse),
297    /// Notification message
298    Notification(JsonRpcNotification),
299}
300
301impl JsonRpcRequest {
302    /// Create a new JSON-RPC request
303    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    /// Create a request with no parameters
313    pub fn without_params(method: String, id: RequestId) -> Self {
314        Self::new(method, None, id)
315    }
316
317    /// Create a request with parameters
318    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    /// Create a successful response
330    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    /// Create an error response with request ID
339    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    /// Create a parse error response (id is null)
348    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    /// Check if this is a successful response
362    pub fn is_success(&self) -> bool {
363        matches!(self.payload, JsonRpcResponsePayload::Success { .. })
364    }
365
366    /// Check if this is an error response
367    pub fn is_error(&self) -> bool {
368        matches!(self.payload, JsonRpcResponsePayload::Error { .. })
369    }
370
371    /// Get the result if this is a success response
372    pub fn result(&self) -> Option<&Value> {
373        match &self.payload {
374            JsonRpcResponsePayload::Success { result } => Some(result),
375            JsonRpcResponsePayload::Error { .. } => None,
376        }
377    }
378
379    /// Get the error if this is an error response
380    pub fn error(&self) -> Option<&JsonRpcError> {
381        match &self.payload {
382            JsonRpcResponsePayload::Success { .. } => None,
383            JsonRpcResponsePayload::Error { error } => Some(error),
384        }
385    }
386
387    /// Get the request ID if this is not a parse error
388    pub fn request_id(&self) -> Option<&RequestId> {
389        self.id.as_request_id()
390    }
391
392    /// Check if this response is for a parse error (has null ID)
393    pub fn is_parse_error(&self) -> bool {
394        self.id.is_null()
395    }
396
397    /// Get mutable reference to result if this is a success response
398    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    /// Get mutable reference to error if this is an error response
406    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    /// Set the result for this response (converts to success response)
414    pub fn set_result(&mut self, result: Value) {
415        self.payload = JsonRpcResponsePayload::Success { result };
416    }
417
418    /// Set the error for this response (converts to error response)
419    pub fn set_error(&mut self, error: JsonRpcError) {
420        self.payload = JsonRpcResponsePayload::Error { error };
421    }
422}
423
424impl JsonRpcNotification {
425    /// Create a new JSON-RPC notification
426    pub fn new(method: String, params: Option<Value>) -> Self {
427        Self {
428            jsonrpc: JsonRpcVersion,
429            method,
430            params,
431        }
432    }
433
434    /// Create a notification with no parameters
435    pub fn without_params(method: String) -> Self {
436        Self::new(method, None)
437    }
438
439    /// Create a notification with parameters
440    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
446/// Utility functions for JSON-RPC message handling
447pub mod utils {
448    use super::*;
449
450    /// Parse a JSON-RPC message from a string
451    pub fn parse_message(json: &str) -> Result<JsonRpcMessage, serde_json::Error> {
452        serde_json::from_str(json)
453    }
454
455    /// Serialize a JSON-RPC message to a string
456    pub fn serialize_message(message: &JsonRpcMessage) -> Result<String, serde_json::Error> {
457        serde_json::to_string(message)
458    }
459
460    /// Extract the method name from a JSON-RPC message string
461    pub fn extract_method(json: &str) -> Option<String> {
462        // Simple regex-free method extraction for performance
463        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
472/// HTTP boundary types for lenient JSON-RPC parsing
473///
474/// These types are designed for parsing JSON-RPC messages at HTTP boundaries where
475/// the input may not be strictly compliant. They accept any valid JSON structure
476/// and can be converted to the canonical types after validation.
477///
478/// # Usage
479///
480/// ```rust
481/// use turbomcp_protocol::jsonrpc::http::{HttpJsonRpcRequest, HttpJsonRpcResponse};
482/// use turbomcp_protocol::jsonrpc::JsonRpcError;
483///
484/// // Parse lenient request
485/// let raw_json = r#"{"jsonrpc":"2.0","method":"test","id":1}"#;
486/// let request: HttpJsonRpcRequest = serde_json::from_str(raw_json).unwrap();
487///
488/// // Validate and use
489/// if request.jsonrpc != "2.0" {
490///     // Return error with the id we managed to extract
491/// }
492/// ```
493pub mod http {
494    use serde::{Deserialize, Serialize};
495    use serde_json::Value;
496
497    /// Lenient JSON-RPC request for HTTP boundary parsing
498    ///
499    /// This type accepts any string for `jsonrpc` and any JSON value for `id`,
500    /// allowing proper error handling when clients send non-compliant requests.
501    #[derive(Debug, Clone, Serialize, Deserialize)]
502    pub struct HttpJsonRpcRequest {
503        /// JSON-RPC version (should be "2.0" but accepts any string for error handling)
504        pub jsonrpc: String,
505        /// Request ID (can be string, number, or null)
506        #[serde(default)]
507        pub id: Option<Value>,
508        /// Method name
509        pub method: String,
510        /// Method parameters
511        #[serde(default)]
512        pub params: Option<Value>,
513    }
514
515    impl HttpJsonRpcRequest {
516        /// Check if this is a valid JSON-RPC 2.0 request
517        pub fn is_valid(&self) -> bool {
518            self.jsonrpc == "2.0" && !self.method.is_empty()
519        }
520
521        /// Check if this is a notification (no id)
522        pub fn is_notification(&self) -> bool {
523            self.id.is_none()
524        }
525
526        /// Get the id as a string if it's a string, or convert number to string
527        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    /// Lenient JSON-RPC response for HTTP boundary
537    ///
538    /// Uses separate result/error fields for compatibility with various JSON-RPC
539    /// implementations.
540    #[derive(Debug, Clone, Serialize, Deserialize)]
541    pub struct HttpJsonRpcResponse {
542        /// JSON-RPC version
543        pub jsonrpc: String,
544        /// Response ID
545        #[serde(default)]
546        pub id: Option<Value>,
547        /// Success result
548        #[serde(skip_serializing_if = "Option::is_none")]
549        pub result: Option<Value>,
550        /// Error information
551        #[serde(skip_serializing_if = "Option::is_none")]
552        pub error: Option<super::JsonRpcError>,
553    }
554
555    impl HttpJsonRpcResponse {
556        /// Create a success response
557        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        /// Create an error response
567        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        /// Create an error response from error code
577        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        /// Create an invalid request error response
582        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        /// Create a parse error response (id is always null for parse errors)
587        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        /// Create an internal error response
597        pub fn internal_error(id: Option<Value>, details: &str) -> Self {
598            Self::error(id, super::JsonRpcError::internal_error(details))
599        }
600
601        /// Create a method not found error response
602        pub fn method_not_found(id: Option<Value>, method: &str) -> Self {
603            Self::error(id, super::JsonRpcError::method_not_found(method))
604        }
605
606        /// Check if this is an error response
607        pub fn is_error(&self) -> bool {
608            self.error.is_some()
609        }
610
611        /// Check if this is a success response
612        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)] // Tests cover deprecated batch functionality for defensive deserialization
673mod 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        // Verify the error details
738        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}