use async_trait::async_trait;
use serde_json::Value;
#[async_trait]
pub trait AgentTool: Send + Sync {
fn name(&self) -> &str;
fn description(&self) -> &str;
fn input_schema(&self) -> Value;
async fn execute(&self, input: Value) -> Result<String, String>;
}
#[cfg(test)]
mod tests {
use super::*;
struct MockTool;
#[async_trait]
impl AgentTool for MockTool {
fn name(&self) -> &str {
"mock"
}
fn description(&self) -> &str {
"mock tool for testing"
}
fn input_schema(&self) -> Value {
serde_json::json!({
"type": "object",
"properties": {}
})
}
async fn execute(&self, _input: Value) -> Result<String, String> {
Ok("mock result".to_string())
}
}
#[tokio::test]
async fn test_mock_tool() {
let tool = MockTool;
assert_eq!(tool.name(), "mock");
assert_eq!(tool.description(), "mock tool for testing");
let schema = tool.input_schema();
assert_eq!(schema["type"], "object");
let result = tool.execute(serde_json::json!({})).await;
assert!(result.is_ok());
assert_eq!(result.unwrap(), "mock result");
}
#[tokio::test]
async fn test_trait_object() {
let tool: Box<dyn AgentTool> = Box::new(MockTool);
assert_eq!(tool.name(), "mock");
let result = tool.execute(serde_json::json!({})).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_trait_reference() {
let tool = MockTool;
let ref_tool: &dyn AgentTool = &tool;
assert_eq!(ref_tool.name(), "mock");
let result = ref_tool.execute(serde_json::json!({})).await;
assert!(result.is_ok());
}
}