turul_mcp_json_rpc_server/
notification.rs1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use std::collections::HashMap;
4
5use crate::{request::RequestParams, types::JsonRpcVersion};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct JsonRpcNotification {
10 #[serde(rename = "jsonrpc")]
11 pub version: JsonRpcVersion,
12 pub method: String,
13 #[serde(skip_serializing_if = "Option::is_none")]
14 pub params: Option<RequestParams>,
15}
16
17impl JsonRpcNotification {
18 pub fn new(method: String, params: Option<RequestParams>) -> Self {
19 Self {
20 version: JsonRpcVersion::V2_0,
21 method,
22 params,
23 }
24 }
25
26 pub fn new_no_params(method: String) -> Self {
28 Self::new(method, None)
29 }
30
31 pub fn new_with_object_params(
33 method: String,
34 params: HashMap<String, Value>,
35 ) -> Self {
36 Self::new(method, Some(RequestParams::Object(params)))
37 }
38
39 pub fn new_with_array_params(method: String, params: Vec<Value>) -> Self {
41 Self::new(method, Some(RequestParams::Array(params)))
42 }
43
44 pub fn get_param(&self, name: &str) -> Option<&Value> {
46 self.params.as_ref()?.get(name)
47 }
48
49 pub fn get_param_index(&self, index: usize) -> Option<&Value> {
51 self.params.as_ref()?.get_index(index)
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58 use serde_json::{json, from_str, to_string};
59
60 #[test]
61 fn test_notification_serialization() {
62 let notification = JsonRpcNotification::new_no_params("test_notification".to_string());
63
64 let json_str = to_string(¬ification).unwrap();
65 let parsed: JsonRpcNotification = from_str(&json_str).unwrap();
66
67 assert_eq!(parsed.method, "test_notification");
68 assert!(parsed.params.is_none());
69 }
70
71 #[test]
72 fn test_notification_with_params() {
73 let mut params = HashMap::new();
74 params.insert("message".to_string(), json!("Hello"));
75 params.insert("level".to_string(), json!("info"));
76
77 let notification = JsonRpcNotification::new_with_object_params(
78 "log".to_string(),
79 params,
80 );
81
82 assert_eq!(notification.get_param("message"), Some(&json!("Hello")));
83 assert_eq!(notification.get_param("level"), Some(&json!("info")));
84 }
85
86 #[test]
87 fn test_notification_json_format() {
88 let notification = JsonRpcNotification::new_no_params("ping".to_string());
89 let json_str = to_string(¬ification).unwrap();
90
91 assert!(!json_str.contains("\"id\""));
93 assert!(json_str.contains("\"jsonrpc\":\"2.0\""));
94 assert!(json_str.contains("\"method\":\"ping\""));
95 }
96}