model_context_protocol/
result.rs1use serde::Serialize;
6
7use crate::protocol::{CallToolResult, ToolContent};
8
9pub type ToolResult<T> = Result<T, String>;
22
23pub trait IntoCallToolResult {
25 fn into_call_result(self) -> CallToolResult;
27}
28
29impl<T: Serialize> IntoCallToolResult for ToolResult<T> {
30 fn into_call_result(self) -> CallToolResult {
31 match self {
32 Ok(value) => {
33 let text = match serde_json::to_string_pretty(&value) {
34 Ok(s) => s,
35 Err(e) => format!("Serialization error: {}", e),
36 };
37 CallToolResult {
38 content: vec![ToolContent::text(text)],
39 structured_content: None,
40 is_error: Some(false),
41 }
42 }
43 Err(e) => CallToolResult {
44 content: vec![ToolContent::text(format!("Error: {}", e))],
45 structured_content: None,
46 is_error: Some(true),
47 },
48 }
49 }
50}
51
52impl IntoCallToolResult for CallToolResult {
53 fn into_call_result(self) -> CallToolResult {
54 self
55 }
56}
57
58impl<T: Serialize> From<ToolResult<T>> for CallToolResult {
60 fn from(result: ToolResult<T>) -> Self {
61 result.into_call_result()
62 }
63}
64
65pub fn tool_ok<T: Serialize>(value: T) -> ToolResult<T> {
67 Ok(value)
68}
69
70pub fn tool_err<T>(message: impl Into<String>) -> ToolResult<T> {
72 Err(message.into())
73}
74
75pub fn success_result(text: impl Into<String>) -> CallToolResult {
77 CallToolResult {
78 content: vec![ToolContent::text(text)],
79 structured_content: None,
80 is_error: Some(false),
81 }
82}
83
84pub fn error_result(message: impl Into<String>) -> CallToolResult {
86 CallToolResult {
87 content: vec![ToolContent::text(message)],
88 structured_content: None,
89 is_error: Some(true),
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn test_ok_result_converts() {
99 let result: ToolResult<String> = Ok("success".to_string());
100 let call_result = result.into_call_result();
101 assert_eq!(call_result.is_error, Some(false));
102 assert_eq!(call_result.content.len(), 1);
103 }
104
105 #[test]
106 fn test_err_result_converts() {
107 let result: ToolResult<String> = Err("failed".to_string());
108 let call_result = result.into_call_result();
109 assert_eq!(call_result.is_error, Some(true));
110 }
111
112 #[test]
113 fn test_tool_ok_helper() {
114 let result = tool_ok("hello");
115 assert!(result.is_ok());
116 assert_eq!(result.unwrap(), "hello");
117 }
118
119 #[test]
120 fn test_tool_err_helper() {
121 let result: ToolResult<()> = tool_err("oops");
122 assert!(result.is_err());
123 assert_eq!(result.unwrap_err(), "oops");
124 }
125
126 #[test]
127 fn test_success_result() {
128 let result = success_result("Operation completed");
129 assert_eq!(result.is_error, Some(false));
130 assert!(result.content[0]
131 .as_text()
132 .unwrap()
133 .contains("Operation completed"));
134 }
135
136 #[test]
137 fn test_error_result() {
138 let result = error_result("Something went wrong");
139 assert_eq!(result.is_error, Some(true));
140 assert!(result.content[0]
141 .as_text()
142 .unwrap()
143 .contains("Something went wrong"));
144 }
145}