1use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct JsonRpcRequest {
12 pub jsonrpc: String,
14 pub id: serde_json::Value,
16 pub method: String,
18 #[serde(skip_serializing_if = "Option::is_none")]
20 pub params: Option<serde_json::Value>,
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct JsonRpcResponse {
26 pub jsonrpc: String,
28 pub id: serde_json::Value,
30 #[serde(skip_serializing_if = "Option::is_none")]
32 pub result: Option<serde_json::Value>,
33 #[serde(skip_serializing_if = "Option::is_none")]
35 pub error: Option<JsonRpcError>,
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct JsonRpcNotification {
41 pub jsonrpc: String,
43 pub method: String,
45 #[serde(skip_serializing_if = "Option::is_none")]
47 pub params: Option<serde_json::Value>,
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct JsonRpcError {
53 pub code: i32,
55 pub message: String,
57 #[serde(skip_serializing_if = "Option::is_none")]
59 pub data: Option<serde_json::Value>,
60}
61
62#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct InitializeParams {
65 #[serde(rename = "protocolVersion")]
67 pub protocol_version: String,
68 pub capabilities: ClientCapabilities,
70 #[serde(rename = "clientInfo")]
72 pub client_info: ClientInfo,
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize)]
77pub struct InitializeResult {
78 #[serde(rename = "protocolVersion")]
80 pub protocol_version: String,
81 pub capabilities: ServerCapabilities,
83 #[serde(rename = "serverInfo")]
85 pub server_info: ServerInfo,
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize, Default)]
90pub struct ClientCapabilities {
91 #[serde(skip_serializing_if = "Option::is_none")]
93 pub experimental: Option<HashMap<String, serde_json::Value>>,
94 #[serde(skip_serializing_if = "Option::is_none")]
96 pub sampling: Option<SamplingCapability>,
97}
98
99#[derive(Debug, Clone, Serialize, Deserialize, Default)]
101pub struct ServerCapabilities {
102 #[serde(skip_serializing_if = "Option::is_none")]
104 pub experimental: Option<HashMap<String, serde_json::Value>>,
105 #[serde(skip_serializing_if = "Option::is_none")]
107 pub resources: Option<crate::resources::ResourceCapabilities>,
108 #[serde(skip_serializing_if = "Option::is_none")]
110 pub tools: Option<crate::tools::ToolCapabilities>,
111 #[serde(skip_serializing_if = "Option::is_none")]
113 pub prompts: Option<crate::prompts::PromptCapabilities>,
114}
115
116#[derive(Debug, Clone, Serialize, Deserialize)]
118pub struct SamplingCapability {}
119
120#[derive(Debug, Clone, Serialize, Deserialize)]
122pub struct ClientInfo {
123 pub name: String,
125 pub version: String,
127}
128
129#[derive(Debug, Clone, Serialize, Deserialize)]
131pub struct ServerInfo {
132 pub name: String,
134 pub version: String,
136}
137
138impl JsonRpcRequest {
139 pub fn new(id: serde_json::Value, method: String, params: Option<serde_json::Value>) -> Self {
141 Self {
142 jsonrpc: "2.0".to_string(),
143 id,
144 method,
145 params,
146 }
147 }
148}
149
150impl JsonRpcResponse {
151 pub fn success(id: serde_json::Value, result: serde_json::Value) -> Self {
153 Self {
154 jsonrpc: "2.0".to_string(),
155 id,
156 result: Some(result),
157 error: None,
158 }
159 }
160
161 pub fn error(id: serde_json::Value, error: JsonRpcError) -> Self {
163 Self {
164 jsonrpc: "2.0".to_string(),
165 id,
166 result: None,
167 error: Some(error),
168 }
169 }
170}
171
172impl JsonRpcNotification {
173 pub fn new(method: String, params: Option<serde_json::Value>) -> Self {
175 Self {
176 jsonrpc: "2.0".to_string(),
177 method,
178 params,
179 }
180 }
181}
182
183impl JsonRpcError {
184 pub const PARSE_ERROR: i32 = -32700;
186 pub const INVALID_REQUEST: i32 = -32600;
187 pub const METHOD_NOT_FOUND: i32 = -32601;
188 pub const INVALID_PARAMS: i32 = -32602;
189 pub const INTERNAL_ERROR: i32 = -32603;
190
191 pub fn new(code: i32, message: String, data: Option<serde_json::Value>) -> Self {
193 Self {
194 code,
195 message,
196 data,
197 }
198 }
199
200 pub fn method_not_found(method: &str) -> Self {
202 Self::new(
203 Self::METHOD_NOT_FOUND,
204 format!("Method not found: {}", method),
205 None,
206 )
207 }
208
209 pub fn invalid_params(message: String) -> Self {
211 Self::new(Self::INVALID_PARAMS, message, None)
212 }
213
214 pub fn internal_error(message: String) -> Self {
216 Self::new(Self::INTERNAL_ERROR, message, None)
217 }
218}
219
220#[cfg(test)]
221mod tests {
222 use super::*;
223
224 #[test]
225 fn test_json_rpc_request_serialization() {
226 let request = JsonRpcRequest::new(
227 serde_json::Value::Number(1.into()),
228 "test_method".to_string(),
229 Some(serde_json::json!({"param": "value"})),
230 );
231
232 let json = serde_json::to_string(&request).unwrap();
233 let deserialized: JsonRpcRequest = serde_json::from_str(&json).unwrap();
234
235 assert_eq!(request.jsonrpc, deserialized.jsonrpc);
236 assert_eq!(request.id, deserialized.id);
237 assert_eq!(request.method, deserialized.method);
238 assert_eq!(request.params, deserialized.params);
239 }
240
241 #[test]
242 fn test_json_rpc_response_success() {
243 let response = JsonRpcResponse::success(
244 serde_json::Value::Number(1.into()),
245 serde_json::json!({"success": true}),
246 );
247
248 assert_eq!(response.jsonrpc, "2.0");
249 assert!(response.result.is_some());
250 assert!(response.error.is_none());
251 }
252
253 #[test]
254 fn test_json_rpc_response_error() {
255 let error = JsonRpcError::method_not_found("unknown_method");
256 let response = JsonRpcResponse::error(serde_json::Value::Number(1.into()), error);
257
258 assert_eq!(response.jsonrpc, "2.0");
259 assert!(response.result.is_none());
260 assert!(response.error.is_some());
261 }
262
263 #[test]
264 fn test_initialize_params() {
265 let params = InitializeParams {
266 protocol_version: "2024-11-05".to_string(),
267 capabilities: ClientCapabilities::default(),
268 client_info: ClientInfo {
269 name: "test-client".to_string(),
270 version: "1.0.0".to_string(),
271 },
272 };
273
274 let json = serde_json::to_string(¶ms).unwrap();
275 let deserialized: InitializeParams = serde_json::from_str(&json).unwrap();
276
277 assert_eq!(params.protocol_version, deserialized.protocol_version);
278 assert_eq!(params.client_info.name, deserialized.client_info.name);
279 }
280}