use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct JsonRpcRequest {
pub jsonrpc: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<serde_json::Value>,
pub method: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub params: Option<serde_json::Value>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_request_serialize() {
let request = JsonRpcRequest {
jsonrpc: "2.0".to_string(),
id: Some(serde_json::json!(1)),
method: "initialize".to_string(),
params: Some(serde_json::json!({"key": "value"})),
};
let json = serde_json::to_string(&request).unwrap();
assert!(json.contains("\"jsonrpc\":\"2.0\""));
assert!(json.contains("\"method\":\"initialize\""));
assert!(json.contains("\"id\":1"));
}
#[test]
fn test_request_deserialize() {
let json = r#"{"jsonrpc":"2.0","id":1,"method":"tools/list","params":null}"#;
let request: JsonRpcRequest = serde_json::from_str(json).unwrap();
assert_eq!(request.jsonrpc, "2.0");
assert_eq!(request.id, Some(serde_json::json!(1)));
assert_eq!(request.method, "tools/list");
}
#[test]
fn test_request_notification_no_id() {
let json = r#"{"jsonrpc":"2.0","method":"notifications/initialized"}"#;
let request: JsonRpcRequest = serde_json::from_str(json).unwrap();
assert_eq!(request.id, None);
assert_eq!(request.method, "notifications/initialized");
assert_eq!(request.params, None);
}
#[test]
fn test_request_round_trip() {
let request = JsonRpcRequest {
jsonrpc: "2.0".to_string(),
id: Some(serde_json::json!(42)),
method: "tools/call".to_string(),
params: Some(serde_json::json!({"name": "greet"})),
};
let json = serde_json::to_string(&request).unwrap();
let deserialized: JsonRpcRequest = serde_json::from_str(&json).unwrap();
assert_eq!(request, deserialized);
}
}