1use std::fmt;
2
3use serde::{
4 Deserialize, Deserializer, Serialize, Serializer,
5 de::{self, MapAccess, Visitor},
6};
7use serde_json::value::RawValue;
8
9use crate::{ErrorCode, Id};
10
11#[derive(Clone, Debug, Serialize, Deserialize)]
16pub struct Error {
17 pub code: i32,
19 pub message: String,
21 #[serde(skip_serializing_if = "Option::is_none")]
23 pub data: Option<Box<RawValue>>,
24}
25
26impl Error {
27 pub fn new(code: i32, message: impl Into<String>) -> Self {
29 Self {
30 code,
31 message: message.into(),
32 data: None,
33 }
34 }
35
36 pub fn with_data(code: i32, message: impl Into<String>, data: impl Serialize) -> serde_json::Result<Self> {
38 Ok(Self {
39 code,
40 message: message.into(),
41 data: Some(serde_json::value::to_raw_value(&data)?),
42 })
43 }
44
45 pub fn parse_error() -> Self {
47 Self::new(ErrorCode::PARSE_ERROR, ErrorCode::default_message(ErrorCode::PARSE_ERROR))
48 }
49
50 pub fn invalid_request(message: impl Into<String>) -> Self {
52 Self::new(ErrorCode::INVALID_REQUEST, message)
53 }
54
55 pub fn method_not_found(method: impl Into<String>) -> Self {
57 Self::new(ErrorCode::METHOD_NOT_FOUND, format!("Method not found: {}", method.into()))
58 }
59
60 pub fn invalid_params(message: impl Into<String>) -> Self {
62 Self::new(ErrorCode::INVALID_PARAMS, message)
63 }
64
65 pub fn internal_error() -> Self {
67 Self::new(ErrorCode::INTERNAL_ERROR, ErrorCode::default_message(ErrorCode::INTERNAL_ERROR))
68 }
69
70 pub fn is_reserved_code(&self) -> bool {
72 ErrorCode::is_reserved(self.code)
73 }
74}
75
76#[derive(Clone, Debug)]
84pub enum Response {
85 Success {
87 result: Box<RawValue>,
89 id: Id,
91 },
92 Error {
94 error: Error,
96 id: Id,
98 },
99}
100
101impl Response {
102 pub fn success(id: Id, result: impl Serialize) -> serde_json::Result<Self> {
104 Ok(Self::Success {
105 result: serde_json::value::to_raw_value(&result)?,
106 id,
107 })
108 }
109
110 pub fn error(id: Id, error: Error) -> Self {
112 Self::Error {
113 error,
114 id,
115 }
116 }
117
118 pub fn result(&self) -> Option<&RawValue> {
120 match self {
121 Self::Success {
122 result, ..
123 } => Some(result),
124 Self::Error {
125 ..
126 } => None,
127 }
128 }
129
130 pub fn error_ref(&self) -> Option<&Error> {
132 match self {
133 Self::Error {
134 error, ..
135 } => Some(error),
136 Self::Success {
137 ..
138 } => None,
139 }
140 }
141
142 pub fn id(&self) -> &Id {
144 match self {
145 Self::Success {
146 id, ..
147 }
148 | Self::Error {
149 id, ..
150 } => id,
151 }
152 }
153
154 pub fn is_success(&self) -> bool {
156 matches!(self, Self::Success { .. })
157 }
158
159 pub fn is_error(&self) -> bool {
161 matches!(self, Self::Error { .. })
162 }
163}
164
165impl Serialize for Response {
166 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
167 use serde::ser::SerializeStruct;
168
169 match self {
170 Self::Success {
171 result,
172 id,
173 } => {
174 let mut s = serializer.serialize_struct("Response", 3)?;
175 s.serialize_field("jsonrpc", "2.0")?;
176 s.serialize_field("result", result)?;
177 s.serialize_field("id", id)?;
178 s.end()
179 }
180 Self::Error {
181 error,
182 id,
183 } => {
184 let mut s = serializer.serialize_struct("Response", 3)?;
185 s.serialize_field("jsonrpc", "2.0")?;
186 s.serialize_field("error", error)?;
187 s.serialize_field("id", id)?;
188 s.end()
189 }
190 }
191 }
192}
193
194impl<'de> Deserialize<'de> for Response {
195 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
196 struct ResponseVisitor;
197
198 impl<'de> Visitor<'de> for ResponseVisitor {
199 type Value = Response;
200
201 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
202 f.write_str("a JSON-RPC 2.0 response object with jsonrpc, result/error, and optional id")
203 }
204
205 fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
206 let mut result: Option<Box<RawValue>> = None;
207 let mut error: Option<Error> = None;
208 let mut id: Option<Id> = None;
209
210 while let Some(key) = map.next_key::<String>()? {
211 match key.as_str() {
212 "jsonrpc" => {
213 let _version: String = map.next_value()?;
214 }
215 "result" => {
216 if error.is_some() {
217 return Err(de::Error::custom("response contains both result and error"));
218 }
219 let raw: Box<RawValue> = map.next_value()?;
220 result = Some(raw);
221 }
222 "error" => {
223 if result.is_some() {
224 return Err(de::Error::custom("response contains both result and error"));
225 }
226 error = Some(map.next_value()?);
227 }
228 "id" => {
229 id = Some(map.next_value()?);
230 }
231 _ => {
232 let _: serde::de::IgnoredAny = map.next_value()?;
233 }
234 }
235 }
236
237 let id = id.ok_or_else(|| de::Error::missing_field("id"))?;
238
239 match (result, error) {
240 (Some(result), None) => Ok(Response::Success {
241 result,
242 id,
243 }),
244 (None, Some(error)) => Ok(Response::Error {
245 error,
246 id,
247 }),
248 (Some(_), Some(_)) => Err(de::Error::custom("response contains both result and error")),
249 (None, None) => Err(de::Error::custom("response missing both result and error")),
250 }
251 }
252 }
253
254 deserializer.deserialize_struct("Response", &["jsonrpc", "result", "error", "id"], ResponseVisitor)
255 }
256}
257
258#[cfg(test)]
259mod tests {
260 use serde_json::{Value, json};
261
262 use super::*;
263
264 #[test]
265 fn test_error_object_new() {
266 let err = Error::new(-32000, "Something went wrong");
267 assert_eq!(err.code, -32000);
268 assert_eq!(err.message, "Something went wrong");
269 assert!(err.data.is_none());
270 }
271
272 #[test]
273 fn test_error_object_with_data() {
274 let err = Error::with_data(-32000, "Server error", json!({"detail": "oops"})).unwrap();
275 assert_eq!(err.code, -32000);
276 assert!(err.data.is_some());
277 }
278
279 #[test]
280 fn test_error_object_serialize() {
281 let err = Error::new(-32601, "Method not found");
282 let json = serde_json::to_value(&err).unwrap();
283 assert_eq!(json["code"], json!(-32601));
284 assert_eq!(json["message"], json!("Method not found"));
285 assert!(json.get("data").is_none());
286 }
287
288 #[test]
289 fn test_error_object_serialize_with_data() {
290 let err = Error::with_data(-32000, "Err", json!(42)).unwrap();
291 let json = serde_json::to_value(&err).unwrap();
292 assert_eq!(json["data"], json!(42));
293 }
294
295 #[test]
296 fn test_error_object_deserialize() {
297 let json = json!({"code": -32601, "message": "Method not found"});
298 let err: Error = serde_json::from_value(json).unwrap();
299 assert_eq!(err.code, -32601);
300 assert_eq!(err.message, "Method not found");
301 assert!(err.data.is_none());
302 }
303
304 #[test]
305 fn test_error_object_deserialize_with_data() {
306 let json = json!({"code": -32000, "message": "Err", "data": 42});
307 let err: Error = serde_json::from_value(json).unwrap();
308 assert_eq!(err.code, -32000);
309 assert!(err.data.is_some());
310 }
311
312 #[test]
313 fn test_error_object_parse_error() {
314 let err = Error::parse_error();
315 assert_eq!(err.code, -32700);
316 }
317
318 #[test]
319 fn test_error_object_invalid_request() {
320 let err = Error::invalid_request("missing jsonrpc");
321 assert_eq!(err.code, -32600);
322 assert!(err.message.contains("missing jsonrpc"));
323 }
324
325 #[test]
326 fn test_error_object_method_not_found() {
327 let err = Error::method_not_found("foo");
328 assert_eq!(err.code, -32601);
329 assert!(err.message.contains("foo"));
330 }
331
332 #[test]
333 fn test_error_object_invalid_params() {
334 let err = Error::invalid_params("expected array");
335 assert_eq!(err.code, -32602);
336 assert!(err.message.contains("expected array"));
337 }
338
339 #[test]
340 fn test_error_object_internal_error() {
341 let err = Error::internal_error();
342 assert_eq!(err.code, -32603);
343 }
344
345 #[test]
346 fn test_error_object_is_reserved_code() {
347 assert!(Error::parse_error().is_reserved_code());
348 assert!(!Error::new(1, "app error").is_reserved_code());
349 }
350
351 #[test]
352 fn test_response_success_serialize() {
353 let resp = Response::success(Id::Number(1), json!(42)).unwrap();
354 assert!(resp.is_success());
355 assert!(!resp.is_error());
356 assert_eq!(resp.id(), &Id::Number(1));
357 assert!(resp.result().is_some());
358 assert!(resp.error_ref().is_none());
359
360 let value = serde_json::to_value(&resp).unwrap();
361 assert_eq!(value["jsonrpc"], json!("2.0"));
362 assert_eq!(value["result"], json!(42));
363 assert_eq!(value["id"], json!(1));
364 }
365
366 #[test]
367 fn test_response_error_serialize() {
368 let err = Error::new(-32601, "Method not found");
369 let resp = Response::error(Id::Null, err);
370 assert!(resp.is_error());
371 assert!(!resp.is_success());
372 assert_eq!(resp.id(), &Id::Null);
373 assert!(resp.result().is_none());
374 assert!(resp.error_ref().is_some());
375
376 let value = serde_json::to_value(&resp).unwrap();
377 assert_eq!(value["jsonrpc"], json!("2.0"));
378 assert!(value.get("result").is_none());
379 assert_eq!(value["error"]["code"], json!(-32601));
380 assert_eq!(value["error"]["message"], json!("Method not found"));
381 assert_eq!(value["id"], json!(null));
382 }
383
384 #[test]
385 fn test_response_success_no_extra_fields() {
386 let resp = Response::success(Id::Number(1), "hello").unwrap();
387 let value: Value = serde_json::to_value(&resp).unwrap();
388 assert!(value.get("error").is_none());
389 }
390
391 #[test]
392 fn test_response_error_no_extra_fields() {
393 let err = Error::new(-32600, "Invalid Request");
394 let resp = Response::error(Id::Null, err);
395 let value: Value = serde_json::to_value(&resp).unwrap();
396 assert!(value.get("result").is_none());
397 }
398
399 #[test]
400 fn test_response_deserialize_success() {
401 let json = json!({"jsonrpc": "2.0", "result": 42, "id": 1});
402 let resp: Response = serde_json::from_value(json).unwrap();
403 assert!(resp.is_success());
404 assert_eq!(resp.id(), &Id::Number(1));
405 assert!(resp.result().is_some());
406 }
407
408 #[test]
409 fn test_response_deserialize_error() {
410 let json = json!({"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "1"});
411 let resp: Response = serde_json::from_value(json).unwrap();
412 assert!(resp.is_error());
413 assert_eq!(resp.id(), &Id::String("1".into()));
414 let err = resp.error_ref().unwrap();
415 assert_eq!(err.code, -32601);
416 }
417
418 #[test]
419 fn test_response_deserialize_missing_both_result_and_error() {
420 let json = json!({"jsonrpc": "2.0", "id": 1});
421 let err = serde_json::from_value::<Response>(json).unwrap_err();
422 assert!(err.to_string().contains("missing both result and error"));
423 }
424
425 #[test]
426 fn test_response_deserialize_both_result_and_error() {
427 let json = json!({"jsonrpc": "2.0", "result": 1, "error": {"code": 0, "message": "x"}, "id": 1});
428 let err = serde_json::from_value::<Response>(json).unwrap_err();
429 assert!(err.to_string().contains("both result and error"));
430 }
431
432 #[test]
433 fn test_response_deserialize_missing_id() {
434 let json = json!({"jsonrpc": "2.0", "result": 42});
435 let err = serde_json::from_value::<Response>(json).unwrap_err();
436 assert!(err.to_string().contains("id"));
437 }
438}