karyon_jsonrpc/
message.rs

1use serde::{Deserialize, Serialize};
2
3use crate::error::RPCError;
4
5pub type ID = u64;
6
7pub const JSONRPC_VERSION: &str = "2.0";
8
9/// Parse error: Invalid JSON was received by the server.
10pub const PARSE_ERROR_CODE: i32 = -32700;
11
12/// Invalid request: The JSON sent is not a valid Request object.
13pub const INVALID_REQUEST_ERROR_CODE: i32 = -32600;
14
15/// Method not found: The method does not exist / is not available.
16pub const METHOD_NOT_FOUND_ERROR_CODE: i32 = -32601;
17
18/// Invalid params: Invalid method parameter(s).
19pub const INVALID_PARAMS_ERROR_CODE: i32 = -32602;
20
21/// Internal error: Internal JSON-RPC error.
22pub const INTERNAL_ERROR_CODE: i32 = -32603;
23
24/// SubscriptionID is used to identify a subscription.
25pub type SubscriptionID = u32;
26
27pub const INTERNAL_ERROR_MSG: &str = "Internal error";
28
29/// Request represents a JSON-RPC request message.
30/// It includes the JSON-RPC version, an identifier for the request, the method
31/// to be invoked, and optional parameters.
32#[derive(Debug, Serialize, Deserialize)]
33pub struct Request {
34    /// JSON-RPC version, typically "2.0".
35    pub jsonrpc: String,
36    /// Unique identifier for the request, can be a number or a string.
37    pub id: serde_json::Value,
38    /// The name of the method to be invoked.
39    pub method: String,
40    /// Optional parameters for the method.
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub params: Option<serde_json::Value>,
43}
44
45/// Response represents a JSON-RPC response message.
46/// It includes the JSON-RPC version, an identifier matching the request, the result of the request,
47/// and an optional error.
48#[derive(Debug, Serialize, Deserialize)]
49#[serde(deny_unknown_fields)]
50pub struct Response {
51    /// JSON-RPC version, typically "2.0".
52    pub jsonrpc: String,
53    /// Unique identifier for the request, can be a number or a string.
54    #[serde(skip_serializing_if = "Option::is_none")]
55    pub id: Option<serde_json::Value>,
56    /// Result of the request if it was successful.
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub result: Option<serde_json::Value>,
59    /// Error object if the request failed.
60    #[serde(skip_serializing_if = "Option::is_none")]
61    pub error: Option<Error>,
62}
63
64/// Notification represents a JSON-RPC notification message.
65#[derive(Debug, Serialize, Deserialize)]
66pub struct Notification {
67    /// JSON-RPC version, typically "2.0".
68    pub jsonrpc: String,
69    /// The name of the method to be invoked.
70    pub method: String,
71    /// Optional parameters for the method.
72    #[serde(skip_serializing_if = "Option::is_none")]
73    pub params: Option<serde_json::Value>,
74}
75
76/// NotificationResult represents the result of a subscription notification.
77/// It includes the result and the subscription ID that triggered the notification.
78#[derive(Debug, Serialize, Deserialize)]
79pub struct NotificationResult {
80    /// Optional data about the notification.
81    pub result: Option<serde_json::Value>,
82    /// ID of the subscription that triggered the notification.
83    pub subscription: SubscriptionID,
84}
85
86// Error represents an error in a JSON-RPC response.
87// It includes an error code, a message, and optional additional data.
88#[derive(Debug, Serialize, Deserialize)]
89pub struct Error {
90    /// Error code indicating the type of error.
91    pub code: i32,
92    /// Human-readable error message.
93    pub message: String,
94    /// Optional additional data about the error.
95    #[serde(skip_serializing_if = "Option::is_none")]
96    pub data: Option<serde_json::Value>,
97}
98
99impl std::fmt::Display for Request {
100    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101        write!(
102            f,
103            "{{jsonrpc: {}, method: {}, params: {:?}, id: {:?}}}",
104            self.jsonrpc, self.method, self.params, self.id,
105        )
106    }
107}
108
109impl std::fmt::Display for Response {
110    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111        write!(
112            f,
113            "{{jsonrpc: {}, result': {:?}, error: {:?} , id: {:?}}}",
114            self.jsonrpc, self.result, self.error, self.id,
115        )
116    }
117}
118
119impl std::fmt::Display for Error {
120    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121        write!(
122            f,
123            "RpcError {{ code: {}, message: {}, data: {:?} }} ",
124            self.code, self.message, self.data
125        )
126    }
127}
128
129impl std::fmt::Display for Notification {
130    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
131        write!(
132            f,
133            "{{jsonrpc: {}, method: {:?}, params: {:?}}}",
134            self.jsonrpc, self.method, self.params
135        )
136    }
137}
138
139impl Default for Response {
140    fn default() -> Self {
141        Self {
142            jsonrpc: JSONRPC_VERSION.to_string(),
143            error: None,
144            id: None,
145            result: None,
146        }
147    }
148}
149
150impl RPCError {
151    pub fn to_response(
152        &self,
153        id: Option<serde_json::Value>,
154        data: Option<serde_json::Value>,
155    ) -> Response {
156        let err: Error = match self {
157            RPCError::ParseError(msg) => Error {
158                code: PARSE_ERROR_CODE,
159                message: msg.to_string(),
160                data,
161            },
162            RPCError::InvalidParams(msg) => Error {
163                code: INVALID_PARAMS_ERROR_CODE,
164                message: msg.to_string(),
165                data,
166            },
167            RPCError::InvalidRequest(msg) => Error {
168                code: INVALID_REQUEST_ERROR_CODE,
169                message: msg.to_string(),
170                data,
171            },
172            RPCError::CustomError(code, msg) => Error {
173                code: *code,
174                message: msg.to_string(),
175                data,
176            },
177            RPCError::InternalError => Error {
178                code: INTERNAL_ERROR_CODE,
179                message: INTERNAL_ERROR_MSG.to_string(),
180                data,
181            },
182        };
183
184        Response {
185            jsonrpc: JSONRPC_VERSION.to_string(),
186            error: Some(err),
187            result: None,
188            id,
189        }
190    }
191}