turul_mcp_json_rpc_server/
response.rs1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4use crate::error::JsonRpcError;
5use crate::types::{JsonRpcVersion, RequestId};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
9#[serde(untagged)]
10pub enum ResponseResult {
11 Success(Value),
13 Null,
15}
16
17impl ResponseResult {
18 pub fn success(value: Value) -> Self {
19 ResponseResult::Success(value)
20 }
21
22 pub fn null() -> Self {
23 ResponseResult::Null
24 }
25
26 pub fn is_null(&self) -> bool {
27 matches!(self, ResponseResult::Null)
28 }
29
30 pub fn as_value(&self) -> Option<&Value> {
31 match self {
32 ResponseResult::Success(value) => Some(value),
33 ResponseResult::Null => None,
34 }
35 }
36}
37
38impl From<Value> for ResponseResult {
39 fn from(value: Value) -> Self {
40 if value.is_null() {
41 ResponseResult::Null
42 } else {
43 ResponseResult::Success(value)
44 }
45 }
46}
47
48impl From<()> for ResponseResult {
49 fn from(_: ()) -> Self {
50 ResponseResult::Null
51 }
52}
53
54#[derive(Debug, Clone, Serialize, Deserialize)]
56pub struct JsonRpcResponse {
57 #[serde(rename = "jsonrpc")]
58 pub version: JsonRpcVersion,
59 pub id: RequestId,
60 pub result: ResponseResult,
61}
62
63impl JsonRpcResponse {
64 pub fn new(id: RequestId, result: ResponseResult) -> Self {
65 Self {
66 version: JsonRpcVersion::V2_0,
67 id,
68 result,
69 }
70 }
71
72 pub fn success(id: RequestId, result: Value) -> Self {
73 Self::new(id, ResponseResult::Success(result))
74 }
75
76 pub fn null(id: RequestId) -> Self {
77 Self::new(id, ResponseResult::Null)
78 }
79}
80
81impl<T> From<(RequestId, T)> for JsonRpcResponse
82where
83 T: Into<ResponseResult>,
84{
85 fn from((id, result): (RequestId, T)) -> Self {
86 Self::new(id, result.into())
87 }
88}
89
90#[derive(Debug, Clone, Serialize, Deserialize)]
93#[serde(untagged)]
94pub enum JsonRpcMessage {
95 Response(JsonRpcResponse),
97 Error(JsonRpcError),
99}
100
101impl JsonRpcMessage {
102 pub fn success(id: RequestId, result: ResponseResult) -> Self {
104 Self::Response(JsonRpcResponse::new(id, result))
105 }
106
107 pub fn error(error: JsonRpcError) -> Self {
109 Self::Error(error)
110 }
111
112 pub fn is_error(&self) -> bool {
114 matches!(self, JsonRpcMessage::Error(_))
115 }
116
117 pub fn id(&self) -> Option<&RequestId> {
119 match self {
120 JsonRpcMessage::Response(resp) => Some(&resp.id),
121 JsonRpcMessage::Error(err) => err.id.as_ref(),
122 }
123 }
124}
125
126impl From<JsonRpcResponse> for JsonRpcMessage {
127 fn from(response: JsonRpcResponse) -> Self {
128 Self::Response(response)
129 }
130}
131
132impl From<JsonRpcError> for JsonRpcMessage {
133 fn from(error: JsonRpcError) -> Self {
134 Self::Error(error)
135 }
136}
137
138#[cfg(test)]
139mod tests {
140 use super::*;
141 use serde_json::{from_str, json, to_string};
142
143 #[test]
144 fn test_response_serialization() {
145 let response = JsonRpcResponse::success(RequestId::Number(1), json!({"result": "success"}));
146
147 let json_str = to_string(&response).unwrap();
148 let parsed: JsonRpcResponse = from_str(&json_str).unwrap();
149
150 assert_eq!(parsed.id, RequestId::Number(1));
151 assert!(matches!(parsed.result, ResponseResult::Success(_)));
152 }
153
154 #[test]
155 fn test_null_response() {
156 let response = JsonRpcResponse::null(RequestId::String("test".to_string()));
157
158 let json_str = to_string(&response).unwrap();
159 println!("JSON: {}", json_str); let parsed: JsonRpcResponse = from_str(&json_str).unwrap();
161 println!("Parsed result: {:?}", parsed.result); assert_eq!(parsed.id, RequestId::String("test".to_string()));
164 match parsed.result {
167 ResponseResult::Success(ref val) if val.is_null() => {} ResponseResult::Null => {} _ => panic!("Expected null result, got: {:?}", parsed.result),
170 }
171 }
172
173 #[test]
174 fn test_response_result_conversion() {
175 let value_result: ResponseResult = json!({"data": 42}).into();
176 assert!(matches!(value_result, ResponseResult::Success(_)));
177
178 let null_result: ResponseResult = json!(null).into();
179 assert!(matches!(null_result, ResponseResult::Null));
180
181 let void_result: ResponseResult = ().into();
182 assert!(matches!(void_result, ResponseResult::Null));
183 }
184
185 #[test]
186 fn test_response_from_tuple() {
187 let response: JsonRpcResponse = (RequestId::Number(1), json!({"test": true})).into();
188 assert_eq!(response.id, RequestId::Number(1));
189 assert!(matches!(response.result, ResponseResult::Success(_)));
190 }
191}