turul_mcp_json_rpc_server/
response.rs1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4use crate::types::{RequestId, JsonRpcVersion};
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
8#[serde(untagged)]
9pub enum ResponseResult {
10 Success(Value),
12 Null,
14}
15
16impl ResponseResult {
17 pub fn success(value: Value) -> Self {
18 ResponseResult::Success(value)
19 }
20
21 pub fn null() -> Self {
22 ResponseResult::Null
23 }
24
25 pub fn is_null(&self) -> bool {
26 matches!(self, ResponseResult::Null)
27 }
28
29 pub fn as_value(&self) -> Option<&Value> {
30 match self {
31 ResponseResult::Success(value) => Some(value),
32 ResponseResult::Null => None,
33 }
34 }
35}
36
37impl From<Value> for ResponseResult {
38 fn from(value: Value) -> Self {
39 if value.is_null() {
40 ResponseResult::Null
41 } else {
42 ResponseResult::Success(value)
43 }
44 }
45}
46
47impl From<()> for ResponseResult {
48 fn from(_: ()) -> Self {
49 ResponseResult::Null
50 }
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct JsonRpcResponse {
56 #[serde(rename = "jsonrpc")]
57 pub version: JsonRpcVersion,
58 pub id: RequestId,
59 pub result: ResponseResult,
60}
61
62impl JsonRpcResponse {
63 pub fn new(id: RequestId, result: ResponseResult) -> Self {
64 Self {
65 version: JsonRpcVersion::V2_0,
66 id,
67 result,
68 }
69 }
70
71 pub fn success(id: RequestId, result: Value) -> Self {
72 Self::new(id, ResponseResult::Success(result))
73 }
74
75 pub fn null(id: RequestId) -> Self {
76 Self::new(id, ResponseResult::Null)
77 }
78}
79
80impl<T> From<(RequestId, T)> for JsonRpcResponse
81where
82 T: Into<ResponseResult>,
83{
84 fn from((id, result): (RequestId, T)) -> Self {
85 Self::new(id, result.into())
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92 use serde_json::{json, from_str, to_string};
93
94 #[test]
95 fn test_response_serialization() {
96 let response = JsonRpcResponse::success(
97 RequestId::Number(1),
98 json!({"result": "success"}),
99 );
100
101 let json_str = to_string(&response).unwrap();
102 let parsed: JsonRpcResponse = from_str(&json_str).unwrap();
103
104 assert_eq!(parsed.id, RequestId::Number(1));
105 assert!(matches!(parsed.result, ResponseResult::Success(_)));
106 }
107
108 #[test]
109 fn test_null_response() {
110 let response = JsonRpcResponse::null(RequestId::String("test".to_string()));
111
112 let json_str = to_string(&response).unwrap();
113 println!("JSON: {}", json_str); let parsed: JsonRpcResponse = from_str(&json_str).unwrap();
115 println!("Parsed result: {:?}", parsed.result); assert_eq!(parsed.id, RequestId::String("test".to_string()));
118 match parsed.result {
121 ResponseResult::Success(ref val) if val.is_null() => {}, ResponseResult::Null => {}, _ => panic!("Expected null result")
124 }
125 }
126
127 #[test]
128 fn test_response_result_conversion() {
129 let value_result: ResponseResult = json!({"data": 42}).into();
130 assert!(matches!(value_result, ResponseResult::Success(_)));
131
132 let null_result: ResponseResult = json!(null).into();
133 assert!(matches!(null_result, ResponseResult::Null));
134
135 let void_result: ResponseResult = ().into();
136 assert!(matches!(void_result, ResponseResult::Null));
137 }
138
139 #[test]
140 fn test_response_from_tuple() {
141 let response: JsonRpcResponse = (RequestId::Number(1), json!({"test": true})).into();
142 assert_eq!(response.id, RequestId::Number(1));
143 assert!(matches!(response.result, ResponseResult::Success(_)));
144 }
145}