1use serde::{Deserialize, Serialize};
6use serde_json::{json, Value};
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct ToolSuccess<T = Value> {
11 #[serde(flatten)]
13 pub data: T,
14
15 #[serde(skip_serializing_if = "Option::is_none")]
17 pub message: Option<String>,
18}
19
20impl<T> ToolSuccess<T> {
21 pub fn new(data: T) -> Self {
23 Self {
24 data,
25 message: None,
26 }
27 }
28
29 pub fn with_message(mut self, message: impl Into<String>) -> Self {
31 self.message = Some(message.into());
32 self
33 }
34}
35
36impl ToolSuccess<Value> {
37 pub fn empty() -> Self {
39 Self {
40 data: json!({}),
41 message: None,
42 }
43 }
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct ToolStatus {
49 pub success: bool,
51
52 pub message: String,
54
55 #[serde(skip_serializing_if = "Option::is_none")]
57 pub details: Option<Value>,
58}
59
60impl ToolStatus {
61 pub fn success(message: impl Into<String>) -> Self {
63 Self {
64 success: true,
65 message: message.into(),
66 details: None,
67 }
68 }
69
70 pub fn error(message: impl Into<String>) -> Self {
72 Self {
73 success: false,
74 message: message.into(),
75 details: None,
76 }
77 }
78
79 pub fn with_details(mut self, details: Value) -> Self {
81 self.details = Some(details);
82 self
83 }
84}
85
86pub fn tool_success<T: Serialize>(data: T) -> Result<Value, crate::error::ToolError> {
88 serde_json::to_value(data)
89 .map_err(|e| crate::error::ToolError::internal(format!("Serialization failed: {}", e)))
90}
91
92pub fn tool_ok(message: impl Into<String>) -> Result<Value, crate::error::ToolError> {
94 Ok(json!({
95 "success": true,
96 "message": message.into()
97 }))
98}
99
100#[cfg(test)]
103mod tests {
104 use super::*;
105 use serde_json::json;
106
107 #[test]
108 fn test_tool_success_new() {
109 let data = json!({"count": 42});
110 let success = ToolSuccess::new(data.clone());
111
112 assert_eq!(success.data, data);
113 assert_eq!(success.message, None);
114 }
115
116 #[test]
117 fn test_tool_success_with_message() {
118 let data = json!({"result": "ok"});
119 let success = ToolSuccess::new(data.clone()).with_message("Operation completed");
120
121 assert_eq!(success.data, data);
122 assert_eq!(success.message, Some("Operation completed".to_string()));
123 }
124
125 #[test]
126 fn test_tool_success_empty() {
127 let success = ToolSuccess::empty();
128 assert_eq!(success.data, json!({}));
129 assert_eq!(success.message, None);
130 }
131
132 #[test]
133 fn test_tool_success_serialization() {
134 let success = ToolSuccess::new(json!({"value": 100})).with_message("Done");
135
136 let serialized = serde_json::to_value(&success).unwrap();
137 assert_eq!(serialized["value"], 100);
138 assert_eq!(serialized["message"], "Done");
139 }
140
141 #[test]
142 fn test_tool_success_no_message_serialization() {
143 let success = ToolSuccess::new(json!({"key": "value"}));
144 let serialized = serde_json::to_value(&success).unwrap();
145
146 assert_eq!(serialized["key"], "value");
147 assert!(!serialized.as_object().unwrap().contains_key("message"));
148 }
149
150 #[test]
151 fn test_tool_status_success() {
152 let status = ToolStatus::success("All good");
153
154 assert!(status.success);
155 assert_eq!(status.message, "All good");
156 assert_eq!(status.details, None);
157 }
158
159 #[test]
160 fn test_tool_status_error() {
161 let status = ToolStatus::error("Something went wrong");
162
163 assert!(!status.success);
164 assert_eq!(status.message, "Something went wrong");
165 assert_eq!(status.details, None);
166 }
167
168 #[test]
169 fn test_tool_status_with_details() {
170 let details = json!({"code": 404, "reason": "not found"});
171 let status = ToolStatus::error("Failed").with_details(details.clone());
172
173 assert!(!status.success);
174 assert_eq!(status.message, "Failed");
175 assert_eq!(status.details, Some(details));
176 }
177
178 #[test]
179 fn test_tool_status_serialization() {
180 let status = ToolStatus::success("Complete").with_details(json!({"items": 5}));
181
182 let serialized = serde_json::to_value(&status).unwrap();
183 assert_eq!(serialized["success"], true);
184 assert_eq!(serialized["message"], "Complete");
185 assert_eq!(serialized["details"]["items"], 5);
186 }
187
188 #[test]
189 fn test_tool_success_helper() {
190 #[derive(Serialize)]
191 struct TestData {
192 name: String,
193 age: u32,
194 }
195
196 let data = TestData {
197 name: "Alice".to_string(),
198 age: 30,
199 };
200
201 let result = tool_success(data).unwrap();
202 assert_eq!(result["name"], "Alice");
203 assert_eq!(result["age"], 30);
204 }
205
206 #[test]
207 fn test_tool_ok_helper() {
208 let result = tool_ok("Task completed").unwrap();
209 assert_eq!(result["success"], true);
210 assert_eq!(result["message"], "Task completed");
211 }
212
213 #[test]
214 fn test_tool_success_with_struct() {
215 #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
216 struct CustomData {
217 id: u64,
218 value: String,
219 }
220
221 let data = CustomData {
222 id: 123,
223 value: "test".to_string(),
224 };
225
226 let success = ToolSuccess::new(data.clone());
227 let serialized = serde_json::to_string(&success).unwrap();
228 let deserialized: ToolSuccess<CustomData> = serde_json::from_str(&serialized).unwrap();
229
230 assert_eq!(deserialized.data, data);
231 }
232}