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(method: String, params: HashMap<String, Value>) -> Self {
33 Self::new(method, Some(RequestParams::Object(params)))
34 }
35
36 pub fn new_with_array_params(method: String, params: Vec<Value>) -> Self {
38 Self::new(method, Some(RequestParams::Array(params)))
39 }
40
41 pub fn get_param(&self, name: &str) -> Option<&Value> {
43 self.params.as_ref()?.get(name)
44 }
45
46 pub fn get_param_index(&self, index: usize) -> Option<&Value> {
48 self.params.as_ref()?.get_index(index)
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55 use serde_json::{from_str, json, to_string};
56
57 #[test]
58 fn test_notification_serialization() {
59 let notification = JsonRpcNotification::new_no_params("test_notification".to_string());
60
61 let json_str = to_string(¬ification).unwrap();
62 let parsed: JsonRpcNotification = from_str(&json_str).unwrap();
63
64 assert_eq!(parsed.method, "test_notification");
65 assert!(parsed.params.is_none());
66 }
67
68 #[test]
69 fn test_notification_with_params() {
70 let mut params = HashMap::new();
71 params.insert("message".to_string(), json!("Hello"));
72 params.insert("level".to_string(), json!("info"));
73
74 let notification = JsonRpcNotification::new_with_object_params("log".to_string(), params);
75
76 assert_eq!(notification.get_param("message"), Some(&json!("Hello")));
77 assert_eq!(notification.get_param("level"), Some(&json!("info")));
78 }
79
80 #[test]
81 fn test_notification_json_format() {
82 let notification = JsonRpcNotification::new_no_params("ping".to_string());
83 let json_str = to_string(¬ification).unwrap();
84
85 assert!(!json_str.contains("\"id\""));
87 assert!(json_str.contains("\"jsonrpc\":\"2.0\""));
88 assert!(json_str.contains("\"method\":\"ping\""));
89 }
90}