1use serde::{Deserialize, Serialize};
4
5pub type RequestId = serde_json::Value;
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct Request {
11 pub jsonrpc: String,
12 pub method: String,
13 #[serde(skip_serializing_if = "Option::is_none")]
14 pub params: Option<serde_json::Value>,
15 #[serde(skip_serializing_if = "Option::is_none")]
16 pub id: Option<RequestId>,
17 #[serde(skip_serializing_if = "Option::is_none")]
18 pub correlation_id: Option<String>,
19}
20
21impl Request {
22 pub fn new(method: impl Into<String>) -> Self {
24 Self {
25 jsonrpc: "2.0".to_owned(),
26 method: method.into(),
27 params: None,
28 id: None,
29 correlation_id: Some(uuid::Uuid::new_v4().to_string()),
30 }
31 }
32
33 #[must_use]
35 pub fn with_params(mut self, params: serde_json::Value) -> Self {
36 self.params = Some(params);
37 self
38 }
39
40 #[must_use]
42 pub fn with_id(mut self, id: RequestId) -> Self {
43 self.id = Some(id);
44 self
45 }
46
47 #[must_use]
49 pub fn expects_response(&self) -> bool {
50 self.id.is_some()
51 }
52
53 #[must_use]
55 pub fn is_notification(&self) -> bool {
56 self.id.is_none()
57 }
58
59 #[must_use]
61 pub fn method(&self) -> &str {
62 &self.method
63 }
64
65 #[must_use]
67 pub fn params(&self) -> Option<&serde_json::Value> {
68 self.params.as_ref()
69 }
70
71 #[must_use]
73 pub fn take_params(self) -> Option<serde_json::Value> {
74 self.params
75 }
76
77 #[must_use]
79 pub fn id(&self) -> Option<&RequestId> {
80 self.id.as_ref()
81 }
82}
83
84#[derive(Debug, Clone, Serialize, Deserialize)]
86pub struct Response {
87 pub jsonrpc: String,
88 #[serde(skip_serializing_if = "Option::is_none")]
89 pub result: Option<serde_json::Value>,
90 #[serde(skip_serializing_if = "Option::is_none")]
91 pub error: Option<crate::Error>,
92 pub id: Option<RequestId>,
93 #[serde(skip_serializing_if = "Option::is_none")]
94 pub correlation_id: Option<String>,
95}
96
97impl Response {
98 #[must_use]
100 pub fn success(result: serde_json::Value, id: Option<RequestId>) -> Self {
101 Self {
102 jsonrpc: "2.0".to_owned(),
103 result: Some(result),
104 error: None,
105 id,
106 correlation_id: None,
107 }
108 }
109
110 #[must_use]
112 pub fn error(error: crate::Error, id: Option<RequestId>) -> Self {
113 Self {
114 jsonrpc: "2.0".to_owned(),
115 result: None,
116 error: Some(error),
117 id,
118 correlation_id: None,
119 }
120 }
121
122 #[must_use]
124 pub fn is_success(&self) -> bool {
125 self.error.is_none() && self.result.is_some()
126 }
127
128 #[must_use]
130 pub fn is_error(&self) -> bool {
131 self.error.is_some()
132 }
133
134 #[must_use]
136 pub fn result(&self) -> Option<&serde_json::Value> {
137 self.result.as_ref()
138 }
139
140 #[must_use]
142 pub fn take_result(self) -> Option<serde_json::Value> {
143 self.result
144 }
145
146 #[must_use]
148 pub fn error_info(&self) -> Option<&crate::Error> {
149 self.error.as_ref()
150 }
151
152 #[must_use]
154 pub fn take_error(self) -> Option<crate::Error> {
155 self.error
156 }
157
158 #[must_use]
160 pub fn id(&self) -> Option<&RequestId> {
161 self.id.as_ref()
162 }
163}
164
165#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
167pub struct Error {
168 pub code: i32,
169 pub message: String,
170 #[serde(skip_serializing_if = "Option::is_none")]
171 pub data: Option<serde_json::Value>,
172}
173
174impl Error {
175 pub fn new(code: i32, message: impl Into<String>) -> Self {
177 Self {
178 code,
179 message: message.into(),
180 data: None,
181 }
182 }
183
184 #[must_use]
186 pub fn with_data(mut self, data: serde_json::Value) -> Self {
187 self.data = Some(data);
188 self
189 }
190
191 #[must_use]
193 pub fn is_parse_error(&self) -> bool {
194 self.code == crate::error_codes::PARSE_ERROR
195 }
196
197 #[must_use]
199 pub fn is_invalid_request(&self) -> bool {
200 self.code == crate::error_codes::INVALID_REQUEST
201 }
202
203 #[must_use]
205 pub fn is_method_not_found(&self) -> bool {
206 self.code == crate::error_codes::METHOD_NOT_FOUND
207 }
208
209 #[must_use]
210 pub fn is_invalid_params(&self) -> bool {
211 self.code == crate::error_codes::INVALID_PARAMS
212 }
213
214 #[must_use]
215 pub fn is_internal_error(&self) -> bool {
216 self.code == crate::error_codes::INTERNAL_ERROR
217 }
218
219 #[must_use]
220 pub fn is_server_error(&self) -> bool {
221 self.code >= -32099 && self.code <= -32000
222 }
223
224 #[must_use]
225 pub fn code(&self) -> i32 {
226 self.code
227 }
228
229 #[must_use]
230 pub fn message(&self) -> &str {
231 &self.message
232 }
233
234 #[must_use]
235 pub fn data(&self) -> Option<&serde_json::Value> {
236 self.data.as_ref()
237 }
238
239 #[must_use]
258 pub fn sanitized_with<F>(&self, transform: F) -> Self
259 where
260 F: FnOnce(&Self) -> Self,
261 {
262 transform(self)
263 }
264
265 pub fn from_error_logged(error: &dyn std::error::Error) -> Self {
270 tracing::error!(
271 error = %error,
272 error_debug = ?error,
273 "internal error occurred"
274 );
275
276 Self {
277 code: crate::error_codes::INTERNAL_ERROR,
278 message: "Internal server error".to_owned(),
279 data: None,
280 }
281 }
282}
283
284#[derive(Debug, Clone, Serialize, Deserialize)]
285pub struct Notification {
286 pub jsonrpc: String,
287 pub method: String,
288 #[serde(skip_serializing_if = "Option::is_none")]
289 pub params: Option<serde_json::Value>,
290}
291
292impl Notification {
293 pub fn new(method: impl Into<String>) -> Self {
294 Self {
295 jsonrpc: "2.0".to_owned(),
296 method: method.into(),
297 params: None,
298 }
299 }
300
301 #[must_use]
302 pub fn with_params(mut self, params: serde_json::Value) -> Self {
303 self.params = Some(params);
304 self
305 }
306
307 #[must_use]
308 pub fn method(&self) -> &str {
309 &self.method
310 }
311
312 #[must_use]
313 pub fn params(&self) -> Option<&serde_json::Value> {
314 self.params.as_ref()
315 }
316
317 #[must_use]
318 pub fn take_params(self) -> Option<serde_json::Value> {
319 self.params
320 }
321}
322
323#[derive(Debug, Clone, Serialize, Deserialize)]
324#[serde(untagged)]
325pub enum Message {
326 Request(Request),
327 Response(Response),
328 Notification(Notification),
329}
330
331impl Message {
332 #[must_use]
333 pub fn is_request(&self) -> bool {
334 matches!(self, Message::Request(_))
335 }
336
337 #[must_use]
338 pub fn is_response(&self) -> bool {
339 matches!(self, Message::Response(_))
340 }
341
342 #[must_use]
343 pub fn is_notification(&self) -> bool {
344 matches!(self, Message::Notification(_))
345 }
346
347 #[must_use]
348 pub fn as_request(&self) -> Option<&Request> {
349 match self {
350 Message::Request(req) => Some(req),
351 _ => None,
352 }
353 }
354
355 #[must_use]
356 pub fn as_response(&self) -> Option<&Response> {
357 match self {
358 Message::Response(resp) => Some(resp),
359 _ => None,
360 }
361 }
362
363 #[must_use]
364 pub fn as_notification(&self) -> Option<&Notification> {
365 match self {
366 Message::Notification(notif) => Some(notif),
367 _ => None,
368 }
369 }
370
371 #[must_use]
372 pub fn into_request(self) -> Option<Request> {
373 match self {
374 Message::Request(req) => Some(req),
375 _ => None,
376 }
377 }
378
379 #[must_use]
380 pub fn into_response(self) -> Option<Response> {
381 match self {
382 Message::Response(resp) => Some(resp),
383 _ => None,
384 }
385 }
386
387 #[must_use]
388 pub fn into_notification(self) -> Option<Notification> {
389 match self {
390 Message::Notification(notif) => Some(notif),
391 _ => None,
392 }
393 }
394
395 #[must_use]
396 pub fn method(&self) -> Option<&str> {
397 match self {
398 Message::Request(req) => Some(&req.method),
399 Message::Notification(notif) => Some(¬if.method),
400 Message::Response(_) => None,
401 }
402 }
403
404 #[must_use]
405 pub fn id(&self) -> Option<&RequestId> {
406 match self {
407 Message::Request(req) => req.id.as_ref(),
408 Message::Response(resp) => resp.id.as_ref(),
409 Message::Notification(_) => None,
410 }
411 }
412}
413
414pub mod error_codes {
428 pub const PARSE_ERROR: i32 = -32700;
431
432 pub const INVALID_REQUEST: i32 = -32600;
434
435 pub const METHOD_NOT_FOUND: i32 = -32601;
437
438 pub const INVALID_PARAMS: i32 = -32602;
440
441 pub const INTERNAL_ERROR: i32 = -32603;
443}
444
445#[cfg(test)]
446mod tests {
447 use super::*;
448 use serde_json::json;
449
450 #[test]
452 fn test_request_creation() {
453 let request = Request::new("test_method");
454 assert_eq!(request.jsonrpc, "2.0");
455 assert_eq!(request.method, "test_method");
456 assert!(request.params.is_none());
457 assert!(request.id.is_none());
458 assert!(request.correlation_id.is_some());
459 }
460
461 #[test]
462 fn test_request_with_params() {
463 let params = json!({"key": "value"});
464 let request = Request::new("method").with_params(params.clone());
465 assert_eq!(request.params(), Some(¶ms));
466 }
467
468 #[test]
469 fn test_request_with_id() {
470 let id = json!(42);
471 let request = Request::new("method").with_id(id.clone());
472 assert_eq!(request.id(), Some(&id));
473 assert!(request.expects_response());
474 assert!(!request.is_notification());
475 }
476
477 #[test]
478 fn test_request_notification() {
479 let request = Request::new("notify");
480 assert!(!request.expects_response());
481 assert!(request.is_notification());
482 }
483
484 #[test]
485 fn test_request_serialization() {
486 let request = Request::new("test")
487 .with_params(json!([1, 2, 3]))
488 .with_id(json!(1));
489
490 let serialized = serde_json::to_string(&request).unwrap();
491 let deserialized: Request = serde_json::from_str(&serialized).unwrap();
492
493 assert_eq!(request.method, deserialized.method);
494 assert_eq!(request.params, deserialized.params);
495 assert_eq!(request.id, deserialized.id);
496 }
497
498 #[test]
499 fn test_request_take_params() {
500 let params = json!([1, 2, 3]);
501 let request = Request::new("test").with_params(params.clone());
502 let taken = request.take_params();
503 assert_eq!(taken, Some(params));
504 }
505
506 #[test]
508 fn test_response_success() {
509 let result = json!({"status": "ok"});
510 let response = Response::success(result.clone(), Some(json!(1)));
511
512 assert!(response.is_success());
513 assert!(!response.is_error());
514 assert_eq!(response.result(), Some(&result));
515 assert!(response.error.is_none());
516 }
517
518 #[test]
519 fn test_response_error() {
520 let error = crate::ErrorBuilder::new(-32600, "Invalid request").build();
521 let response = Response::error(error.clone(), Some(json!(1)));
522
523 assert!(!response.is_success());
524 assert!(response.is_error());
525 assert!(response.result.is_none());
526 assert_eq!(response.error_info().unwrap().code, error.code);
527 }
528
529 #[test]
530 fn test_response_serialization() {
531 let response = Response::success(json!("result"), Some(json!(1)));
532 let serialized = serde_json::to_string(&response).unwrap();
533 let deserialized: Response = serde_json::from_str(&serialized).unwrap();
534
535 assert_eq!(response.result, deserialized.result);
536 assert_eq!(response.id, deserialized.id);
537 }
538
539 #[test]
540 fn test_response_take_result() {
541 let result = json!({"data": "value"});
542 let response = Response::success(result.clone(), Some(json!(1)));
543 let taken = response.take_result();
544 assert_eq!(taken, Some(result));
545 }
546
547 #[test]
548 fn test_response_take_error() {
549 let error = crate::ErrorBuilder::new(-32600, "Error").build();
550 let response = Response::error(error.clone(), Some(json!(1)));
551 let taken = response.take_error();
552 assert!(taken.is_some());
553 assert_eq!(taken.unwrap().code(), error.code());
554 }
555
556 #[test]
558 fn test_error_creation() {
559 let error = crate::ErrorBuilder::new(-32600, "Test error").build();
560 assert_eq!(error.code(), -32600);
561 assert_eq!(error.message(), "Test error");
562 assert!(error.data().is_none());
563 }
564
565 #[test]
566 fn test_error_with_data() {
567 let data = json!({"details": "more info"});
568 let error = crate::ErrorBuilder::new(-32000, "Error")
569 .data(data.clone())
570 .build();
571 assert_eq!(error.data(), Some(&data));
572 }
573
574 #[test]
575 fn test_error_type_checks() {
576 assert!(
577 crate::ErrorBuilder::new(error_codes::PARSE_ERROR, "msg")
578 .build()
579 .is_parse_error()
580 );
581 assert!(
582 crate::ErrorBuilder::new(error_codes::INVALID_REQUEST, "msg")
583 .build()
584 .is_invalid_request()
585 );
586 assert!(
587 crate::ErrorBuilder::new(error_codes::METHOD_NOT_FOUND, "msg")
588 .build()
589 .is_method_not_found()
590 );
591 assert!(
592 crate::ErrorBuilder::new(error_codes::INVALID_PARAMS, "msg")
593 .build()
594 .is_invalid_params()
595 );
596 assert!(
597 crate::ErrorBuilder::new(error_codes::INTERNAL_ERROR, "msg")
598 .build()
599 .is_internal_error()
600 );
601 assert!(
602 crate::ErrorBuilder::new(-32001, "msg")
603 .build()
604 .is_server_error()
605 );
606 assert!(
607 !crate::ErrorBuilder::new(-32700, "msg")
608 .build()
609 .is_server_error()
610 );
611 }
612
613 #[test]
614 fn test_error_sanitization() {
615 let error = crate::ErrorBuilder::new(
616 -32603,
617 "Internal database connection failed: postgres://user:pass@host",
618 )
619 .build();
620 let sanitized = error
621 .sanitized_with(|e| crate::ErrorBuilder::new(e.code, "Internal server error").build());
622
623 assert_eq!(sanitized.code(), error.code());
624 assert_eq!(sanitized.message(), "Internal server error");
625 assert!(!sanitized.message().contains("postgres"));
626 }
627
628 #[test]
629 fn test_error_from_std_error() {
630 let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
631 let error = Error::from_error_logged(&io_error);
632
633 assert_eq!(error.code(), error_codes::INTERNAL_ERROR);
634 assert_eq!(error.message(), "Internal server error");
635 }
636
637 #[test]
639 fn test_notification_creation() {
640 let notification = Notification::new("notify");
641 assert_eq!(notification.jsonrpc, "2.0");
642 assert_eq!(notification.method(), "notify");
643 assert!(notification.params().is_none());
644 }
645
646 #[test]
647 fn test_notification_with_params() {
648 let params = json!({"event": "update"});
649 let notification = Notification::new("notify").with_params(params.clone());
650 assert_eq!(notification.params(), Some(¶ms));
651 }
652
653 #[test]
654 fn test_notification_serialization() {
655 let notification = Notification::new("event").with_params(json!([1, 2]));
656 let serialized = serde_json::to_string(¬ification).unwrap();
657 let deserialized: Notification = serde_json::from_str(&serialized).unwrap();
658
659 assert_eq!(notification.method, deserialized.method);
660 assert_eq!(notification.params, deserialized.params);
661 }
662
663 #[test]
664 fn test_notification_take_params() {
665 let params = json!({"event": "data"});
666 let notification = Notification::new("notify").with_params(params.clone());
667 let taken = notification.take_params();
668 assert_eq!(taken, Some(params));
669 }
670
671 #[test]
673 fn test_message_request_variant() {
674 let request = Request::new("test");
675 let message = Message::Request(request);
676
677 assert!(message.is_request());
678 assert!(!message.is_response());
679 assert!(!message.is_notification());
680 }
681
682 #[test]
683 fn test_message_response_variant() {
684 let response = Response::success(json!("ok"), Some(json!(1)));
685 let message = Message::Response(response);
686
687 assert!(!message.is_request());
688 assert!(message.is_response());
689 assert!(!message.is_notification());
690 }
691
692 #[test]
693 fn test_message_notification_variant() {
694 let notification = Notification::new("event");
695 let message = Message::Notification(notification);
696
697 assert!(!message.is_request());
698 assert!(!message.is_response());
699 assert!(message.is_notification());
700 }
701
702 #[test]
703 fn test_message_serialization_request() {
704 let request = Request::new("test").with_id(json!(1));
705 let message = Message::Request(request);
706
707 let serialized = serde_json::to_string(&message).unwrap();
708 let deserialized: Message = serde_json::from_str(&serialized).unwrap();
709
710 assert!(deserialized.is_request());
711 }
712
713 #[test]
715 fn test_message_as_request() {
716 let request = Request::new("test");
717 let message = Message::Request(request.clone());
718
719 assert!(message.as_request().is_some());
720 assert_eq!(message.as_request().unwrap().method, "test");
721 assert!(message.as_response().is_none());
722 assert!(message.as_notification().is_none());
723 }
724
725 #[test]
726 fn test_message_as_response() {
727 let response = Response::success(json!(42), Some(json!(1)));
728 let message = Message::Response(response);
729
730 assert!(message.as_response().is_some());
731 assert!(message.as_request().is_none());
732 assert!(message.as_notification().is_none());
733 }
734
735 #[test]
736 fn test_message_as_notification() {
737 let notification = Notification::new("event");
738 let message = Message::Notification(notification);
739
740 assert!(message.as_notification().is_some());
741 assert_eq!(message.as_notification().unwrap().method, "event");
742 assert!(message.as_request().is_none());
743 assert!(message.as_response().is_none());
744 }
745
746 #[test]
747 fn test_message_into_request() {
748 let request = Request::new("test");
749 let message = Message::Request(request);
750
751 let extracted = message.into_request();
752 assert!(extracted.is_some());
753 assert_eq!(extracted.unwrap().method, "test");
754 }
755
756 #[test]
757 fn test_message_into_response() {
758 let response = Response::success(json!(true), Some(json!(1)));
759 let message = Message::Response(response);
760
761 let extracted = message.into_response();
762 assert!(extracted.is_some());
763 assert!(extracted.unwrap().is_success());
764 }
765
766 #[test]
767 fn test_message_into_notification() {
768 let notification = Notification::new("notify");
769 let message = Message::Notification(notification);
770
771 let extracted = message.into_notification();
772 assert!(extracted.is_some());
773 assert_eq!(extracted.unwrap().method, "notify");
774 }
775
776 #[test]
777 fn test_message_into_wrong_type() {
778 let message = Message::Request(Request::new("test"));
779 assert!(message.clone().into_response().is_none());
780 assert!(message.into_notification().is_none());
781 }
782
783 #[test]
784 fn test_message_method_from_request() {
785 let request = Request::new("my_method");
786 let message = Message::Request(request);
787 assert_eq!(message.method(), Some("my_method"));
788 }
789
790 #[test]
791 fn test_message_method_from_notification() {
792 let notification = Notification::new("event_method");
793 let message = Message::Notification(notification);
794 assert_eq!(message.method(), Some("event_method"));
795 }
796
797 #[test]
798 fn test_message_method_from_response() {
799 let response = Response::success(json!(1), Some(json!(1)));
800 let message = Message::Response(response);
801 assert_eq!(message.method(), None);
802 }
803
804 #[test]
805 fn test_message_id_from_request() {
806 let request = Request::new("test").with_id(json!(123));
807 let message = Message::Request(request);
808 assert_eq!(message.id(), Some(&json!(123)));
809 }
810
811 #[test]
812 fn test_message_id_from_response() {
813 let response = Response::success(json!(1), Some(json!("abc")));
814 let message = Message::Response(response);
815 assert_eq!(message.id(), Some(&json!("abc")));
816 }
817
818 #[test]
819 fn test_message_id_from_notification() {
820 let notification = Notification::new("event");
821 let message = Message::Notification(notification);
822 assert_eq!(message.id(), None);
823 }
824
825 #[test]
826 fn test_message_id_none() {
827 let request = Request::new("test"); let message = Message::Request(request);
829 assert_eq!(message.id(), None);
830 }
831
832 #[test]
834 fn test_request_method_accessor() {
835 let request = Request::new("get_data");
836 assert_eq!(request.method(), "get_data");
837 }
838
839 #[test]
840 fn test_request_params_accessor() {
841 let params = json!({"key": "value"});
842 let request = Request::new("test").with_params(params.clone());
843 assert_eq!(request.params(), Some(¶ms));
844 }
845
846 #[test]
847 fn test_request_params_none() {
848 let request = Request::new("test");
849 assert_eq!(request.params(), None);
850 }
851
852 #[test]
853 fn test_request_id_accessor() {
854 let request = Request::new("test").with_id(json!(999));
855 assert_eq!(request.id(), Some(&json!(999)));
856 }
857
858 #[test]
860 fn test_response_result_accessor() {
861 let result = json!({"data": "value"});
862 let response = Response::success(result.clone(), Some(json!(1)));
863 assert_eq!(response.result(), Some(&result));
864 }
865
866 #[test]
867 fn test_response_error_info() {
868 let error = crate::ErrorBuilder::new(-32600, "Invalid Request").build();
869 let response = Response::error(error.clone(), Some(json!(1)));
870 assert!(response.error_info().is_some());
871 assert_eq!(response.error_info().unwrap().code, -32600);
872 }
873
874 #[test]
875 fn test_response_id_accessor() {
876 let response = Response::success(json!(1), Some(json!("req-id")));
877 assert_eq!(response.id(), Some(&json!("req-id")));
878 }
879
880 #[test]
882 fn test_error_code_accessor() {
883 let error = crate::ErrorBuilder::new(-32001, "Custom error").build();
884 assert_eq!(error.code(), -32001);
885 }
886
887 #[test]
888 fn test_error_message_accessor() {
889 let error = crate::ErrorBuilder::new(-32002, "Test message").build();
890 assert_eq!(error.message(), "Test message");
891 }
892
893 #[test]
894 fn test_error_data_accessor() {
895 let data = json!({"detail": "info"});
896 let error = crate::ErrorBuilder::new(-32003, "Error")
897 .data(data.clone())
898 .build();
899 assert_eq!(error.data(), Some(&data));
900 }
901
902 #[test]
903 fn test_error_data_none() {
904 let error = crate::ErrorBuilder::new(-32004, "Error").build();
905 assert_eq!(error.data(), None);
906 }
907
908 #[test]
909 fn test_error_is_invalid_params() {
910 let error = crate::ErrorBuilder::new(error_codes::INVALID_PARAMS, "Invalid").build();
911 assert!(error.is_invalid_params());
912 assert!(!error.is_parse_error());
913 }
914
915 #[test]
916 fn test_error_is_internal_error() {
917 let error = crate::ErrorBuilder::new(error_codes::INTERNAL_ERROR, "Internal").build();
918 assert!(error.is_internal_error());
919 assert!(!error.is_server_error());
920 }
921
922 #[test]
923 fn test_error_is_server_error() {
924 let error = crate::ErrorBuilder::new(-32050, "Server error").build();
925 assert!(error.is_server_error());
926 assert!(!error.is_internal_error());
927
928 let error_min = crate::ErrorBuilder::new(-32099, "Min").build();
930 assert!(error_min.is_server_error());
931
932 let error_max = crate::ErrorBuilder::new(-32000, "Max").build();
933 assert!(error_max.is_server_error());
934
935 let error_out = crate::ErrorBuilder::new(-31999, "Out of range").build();
936 assert!(!error_out.is_server_error());
937 }
938
939 #[test]
940 fn test_error_sanitized_with() {
941 let error =
942 crate::ErrorBuilder::new(-32603, "Database connection failed: host=db.internal")
943 .build();
944 let sanitized = error.sanitized_with(|e| {
945 crate::ErrorBuilder::new(e.code(), "Internal server error").build()
946 });
947
948 assert_eq!(sanitized.code(), -32603);
949 assert_eq!(sanitized.message(), "Internal server error");
950 assert!(!sanitized.message().contains("db.internal"));
951 }
952
953 #[test]
955 fn test_notification_method_accessor() {
956 let notification = Notification::new("user_logged_in");
957 assert_eq!(notification.method(), "user_logged_in");
958 }
959
960 #[test]
961 fn test_notification_params_accessor() {
962 let params = json!({"user_id": 123});
963 let notification = Notification::new("event").with_params(params.clone());
964 assert_eq!(notification.params(), Some(¶ms));
965 }
966
967 #[test]
968 fn test_notification_params_none() {
969 let notification = Notification::new("ping");
970 assert_eq!(notification.params(), None);
971 }
972
973 #[test]
975 fn test_error_code_constants() {
976 assert_eq!(error_codes::PARSE_ERROR, -32700);
977 assert_eq!(error_codes::INVALID_REQUEST, -32600);
978 assert_eq!(error_codes::METHOD_NOT_FOUND, -32601);
979 assert_eq!(error_codes::INVALID_PARAMS, -32602);
980 assert_eq!(error_codes::INTERNAL_ERROR, -32603);
981 }
982
983 #[test]
984 fn test_error_from_std_error_logging() {
985 use std::io;
986 let io_error = io::Error::new(io::ErrorKind::NotFound, "file not found");
987 let error = Error::from_error_logged(&io_error);
988
989 assert_eq!(error.code(), error_codes::INTERNAL_ERROR);
990 assert_eq!(error.message(), "Internal server error");
991 }
992
993 #[test]
994 fn test_request_correlation_id() {
995 let request = Request::new("test");
996 assert!(request.correlation_id.is_some());
998 }
999
1000 #[test]
1001 fn test_response_with_correlation_id() {
1002 let mut response = Response::success(json!(1), Some(json!(1)));
1003 response.correlation_id = Some("custom-id".to_string());
1004 assert_eq!(response.correlation_id, Some("custom-id".to_string()));
1005 }
1006}