1use std::fmt;
7
8use serde::{Deserialize, Serialize};
9use tracing::debug;
10
11use crate::error::Error as InternalError;
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct Request {
15 pub jsonrpc: String,
16 pub id: RequestId,
17 pub method: String,
18 #[serde(skip_serializing_if = "Option::is_none")]
19 pub params: Option<serde_json::Value>,
20}
21
22impl Request {
23 pub fn new(
24 id: RequestId,
25 method: impl Into<String>,
26 params: Option<serde_json::Value>,
27 ) -> Self {
28 Self {
29 jsonrpc: "2.0".to_string(),
30 id,
31 method: method.into(),
32 params,
33 }
34 }
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct Response {
39 pub jsonrpc: String,
40 #[serde(skip_serializing_if = "Option::is_none")]
41 pub result: Option<serde_json::Value>,
42 #[serde(skip_serializing_if = "Option::is_none")]
43 pub error: Option<Error>,
44 pub id: RequestId,
45}
46
47impl Response {
48 pub fn success(id: RequestId, result: serde_json::Value) -> Self {
49 Self {
50 jsonrpc: "2.0".to_string(),
51 id,
52 result: Some(result),
53 error: None,
54 }
55 }
56
57 pub fn error(id: RequestId, error: Error) -> Self {
58 Self {
59 jsonrpc: "2.0".to_string(),
60 id,
61 result: None,
62 error: Some(error),
63 }
64 }
65
66 pub fn validate(&self) -> Result<(), String> {
67 match (&self.result, &self.error) {
68 (Some(_), Some(_)) => Err("Response cannot have both result and error".to_string()),
69 (None, None) => Err("Response must have either result or error".to_string()),
70 _ => Ok(()),
71 }
72 }
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct Notification {
77 pub jsonrpc: String,
78 pub method: String,
79 #[serde(skip_serializing_if = "Option::is_none")]
80 pub params: Option<serde_json::Value>,
81}
82
83impl Notification {
84 pub fn new(method: impl Into<String>, params: Option<serde_json::Value>) -> Self {
85 Self {
86 jsonrpc: "2.0".to_string(),
87 method: method.into(),
88 params,
89 }
90 }
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct Error {
95 pub code: i32,
96 pub message: String,
97 #[serde(skip_serializing_if = "Option::is_none")]
98 pub data: Option<serde_json::Value>,
99}
100
101impl Error {
102 pub fn new(code: i32, message: impl Into<String>, data: Option<serde_json::Value>) -> Self {
103 Self {
104 code,
105 message: message.into(),
106 data,
107 }
108 }
109
110 pub fn parse_error(message: impl Into<String>) -> Self {
111 Self::new(-32700, message, None)
112 }
113
114 pub fn invalid_request(message: impl Into<String>) -> Self {
115 Self::new(-32600, message, None)
116 }
117
118 pub fn method_not_found(message: impl Into<String>) -> Self {
119 Self::new(-32601, message, None)
120 }
121
122 pub fn invalid_params(message: impl Into<String>) -> Self {
123 Self::new(-32602, message, None)
124 }
125
126 pub fn internal_error(message: impl Into<String>) -> Self {
127 Self::new(-32603, message, None)
128 }
129}
130
131impl fmt::Display for Error {
132 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133 write!(f, "JSON-RPC error {}: {}", self.code, self.message)
134 }
135}
136
137#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
138#[serde(untagged)]
139pub enum RequestId {
140 Null,
141 Number(u64),
142 String(String),
143}
144
145impl fmt::Display for RequestId {
146 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147 match self {
148 RequestId::Null => write!(f, "null"),
149 RequestId::Number(n) => write!(f, "{}", n),
150 RequestId::String(s) => write!(f, "{}", s),
151 }
152 }
153}
154
155#[derive(Debug, Clone)]
156pub enum Message {
157 Request(Request),
158 Response(Response),
159 Notification(Notification),
160 Batch(Vec<Message>),
161}
162
163impl Message {
164 fn extract_request_id(value: &serde_json::Value) -> Option<RequestId> {
166 value.get("id").and_then(|id_value| match id_value {
167 serde_json::Value::Null => Some(RequestId::Null),
168 serde_json::Value::Number(n) => n.as_u64().map(RequestId::Number),
169 serde_json::Value::String(s) => {
170 let id_str = s.to_string();
171 Some(RequestId::String(id_str))
172 }
173 _ => None,
174 })
175 }
176
177 pub fn from_json(value: serde_json::Value) -> Result<Self, InternalError> {
178 debug!("Parsing JSON value: {:?}", value);
179 let value_ref = &value;
180
181 if let Some(arr) = value_ref.as_array() {
182 debug!("Detected batch request with {} items", arr.len());
183 if arr.is_empty() {
184 debug!("Empty array detected - returning Invalid Request error");
185 return Err(InternalError::invalid_request("Invalid Request"));
186 }
187
188 let mut messages = Vec::new();
189 for (index, item) in arr.iter().enumerate() {
190 debug!("Processing batch item {}: {:?}", index, item);
191 match Self::from_json_internal(item.clone()) {
192 Ok(msg) => {
193 debug!("Batch item {} parsed successfully", index);
194 messages.push(msg);
195 }
196 Err(e) => {
197 debug!("Batch item {} failed to parse: {:?}", index, e);
198 let id = Self::extract_request_id(item);
199 if let Some(id) = id {
200 let error_response =
201 Response::error(id, Error::invalid_request("Invalid Request"));
202 messages.push(Message::Response(error_response));
203 } else if item.get("method").is_some() {
204 debug!(
205 "Batch item {} is a notification (has method but no id), skipping",
206 index
207 );
208 } else {
209 debug!(
210 "Batch item {} is invalid (no id or method), creating error response",
211 index
212 );
213 let error_response = Response::error(
214 RequestId::Null,
215 Error::invalid_request("Invalid Request"),
216 );
217 messages.push(Message::Response(error_response));
218 }
219 }
220 }
221 }
222 debug!("Batch parsing complete, {} messages", messages.len());
223 return Ok(Message::Batch(messages));
224 }
225
226 if value_ref.get("id").is_some() {
227 debug!("Message has 'id' field, checking for error/method");
228 if value_ref.get("error").is_some() {
229 debug!("Message has 'error' field, parsing as Response");
230 serde_json::from_value(value)
231 .map(Message::Response)
232 .map_err(|e| {
233 debug!("Failed to parse as Response: {}", e);
234 InternalError::invalid_request("Invalid Request")
235 })
236 } else if value_ref.get("method").is_some() {
237 debug!("Message has 'method' field, parsing as Request");
238 let req: Request = serde_json::from_value(value).map_err(|e| {
239 debug!("Failed to deserialize as Request: {}", e);
240 InternalError::invalid_request("Invalid Request")
241 })?;
242
243 if req.jsonrpc != "2.0" {
244 debug!("Invalid jsonrpc value: '{}', expected '2.0'", req.jsonrpc);
245 return Err(InternalError::invalid_request("Invalid Request"));
246 }
247
248 debug!("Request parsed successfully: {}", req.method);
249 Ok(Message::Request(req))
250 } else {
251 debug!("Message has 'id' but no 'method' or 'error' - Invalid Request");
252 Err(InternalError::invalid_request("Invalid Request"))
253 }
254 } else {
255 debug!("Message has no 'id' field, parsing as Notification");
256 let notif: Notification = serde_json::from_value(value).map_err(|e| {
257 debug!("Failed to deserialize as Notification: {}", e);
258 InternalError::invalid_request("Invalid Request")
259 })?;
260
261 if notif.jsonrpc != "2.0" {
262 debug!("Invalid jsonrpc value: '{}', expected '2.0'", notif.jsonrpc);
263 return Err(InternalError::invalid_request("Invalid Request"));
264 }
265
266 debug!("Notification parsed successfully: {}", notif.method);
267 Ok(Message::Notification(notif))
268 }
269 }
270
271 pub fn to_json(&self) -> Result<serde_json::Value, serde_json::Error> {
272 match self {
273 Message::Request(req) => serde_json::to_value(req),
274 Message::Response(res) => serde_json::to_value(res),
275 Message::Notification(notif) => serde_json::to_value(notif),
276 Message::Batch(messages) => {
277 let json_array: Result<Vec<serde_json::Value>, serde_json::Error> =
278 messages.iter().map(|m| m.to_json()).collect();
279 Ok(serde_json::Value::Array(json_array?))
280 }
281 }
282 }
283
284 pub fn id(&self) -> Option<&RequestId> {
285 match self {
286 Message::Request(req) => Some(&req.id),
287 Message::Response(res) => Some(&res.id),
288 Message::Notification(_) => None,
289 Message::Batch(_) => None,
290 }
291 }
292
293 pub fn is_request(&self) -> bool {
294 matches!(self, Message::Request(_))
295 }
296
297 pub fn is_response(&self) -> bool {
298 matches!(self, Message::Response(_))
299 }
300
301 pub fn is_notification(&self) -> bool {
302 matches!(self, Message::Notification(_))
303 }
304
305 pub fn is_batch(&self) -> bool {
306 matches!(self, Message::Batch(_))
307 }
308
309 fn from_json_internal(value: serde_json::Value) -> Result<Self, InternalError> {
310 if value.get("id").is_some() {
311 if value.get("error").is_some() {
312 serde_json::from_value(value)
313 .map(Message::Response)
314 .map_err(|_| InternalError::invalid_request("Invalid Request"))
315 } else if value.get("method").is_some() {
316 serde_json::from_value::<Request>(value)
317 .map(|req| {
318 if req.jsonrpc != "2.0" {
319 return Err(InternalError::invalid_request("Invalid Request"));
320 }
321 Ok(Message::Request(req))
322 })
323 .map_err(|_| InternalError::invalid_request("Invalid Request"))?
324 } else {
325 Err(InternalError::invalid_request("Invalid Request"))
326 }
327 } else {
328 serde_json::from_value::<Notification>(value)
329 .map(|notif| {
330 if notif.jsonrpc != "2.0" {
331 return Err(InternalError::invalid_request("Invalid Request"));
332 }
333 Ok(Message::Notification(notif))
334 })
335 .map_err(|_| InternalError::invalid_request("Invalid Request"))?
336 }
337 }
338}