use kuri_mcp_protocol::{messages::CallToolResult, tool::ToolError, Content};
use std::fmt;
pub trait IntoCallToolResult {
fn into_call_tool_result(self) -> Result<CallToolResult, ToolError>;
}
fn successful_text_response<S: Into<String>>(text: S) -> Result<CallToolResult, ToolError> {
Ok(CallToolResult {
content: vec![Content::text(text)],
is_error: false,
})
}
macro_rules! impl_into_call_tool_result_for_to_string {
($($t:ty),*) => {
$(
impl IntoCallToolResult for $t {
fn into_call_tool_result(self) -> Result<CallToolResult, ToolError> {
successful_text_response(self.to_string())
}
}
)*
};
}
impl_into_call_tool_result_for_to_string!(
String, i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, bool
);
impl IntoCallToolResult for Vec<Content> {
fn into_call_tool_result(self) -> Result<CallToolResult, ToolError> {
Ok(CallToolResult {
content: self,
is_error: false,
})
}
}
impl IntoCallToolResult for () {
fn into_call_tool_result(self) -> Result<CallToolResult, ToolError> {
Ok(CallToolResult {
content: vec![],
is_error: false,
})
}
}
impl<T> IntoCallToolResult for Result<T, ToolError>
where
T: IntoCallToolResult,
{
fn into_call_tool_result(self) -> Result<CallToolResult, ToolError> {
match self {
Ok(value) => value.into_call_tool_result(),
Err(err) => match err {
ToolError::ExecutionError(msg) => Ok(CallToolResult {
content: vec![Content::text(format!("Error: {}", msg))],
is_error: true,
}),
other_err => Err(other_err),
},
}
}
}
impl<T> IntoCallToolResult for Result<T, DisplayableError>
where
T: IntoCallToolResult,
{
fn into_call_tool_result(self) -> Result<CallToolResult, ToolError> {
match self {
Ok(value) => value.into_call_tool_result(),
Err(err) => Ok(CallToolResult {
content: vec![Content::text(err.to_string())],
is_error: true,
}),
}
}
}
#[derive(Debug)]
pub struct DisplayableError(String);
impl fmt::Display for DisplayableError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl<E: Into<String>> From<E> for DisplayableError {
fn from(err: E) -> Self {
DisplayableError(err.into())
}
}