Skip to main content

crates_docs/cli/
test_cmd.rs

1//! Test command implementation
2
3use rust_mcp_sdk::schema::ContentBlock;
4use std::sync::Arc;
5
6/// Test tool command
7#[allow(clippy::too_many_arguments)]
8pub async fn run_test_command(
9    tool: &str,
10    crate_name: Option<&str>,
11    item_path: Option<&str>,
12    query: Option<&str>,
13    version: Option<&str>,
14    limit: u32,
15    format: &str,
16) -> Result<(), Box<dyn std::error::Error>> {
17    tracing::info!("Testing tool: {}", tool);
18
19    // Create cache
20    let cache_config = crate::cache::CacheConfig {
21        cache_type: "memory".to_string(),
22        memory_size: Some(1000),
23        default_ttl: Some(3600),
24        redis_url: None,
25        key_prefix: String::new(),
26    };
27
28    let cache = crate::cache::create_cache(&cache_config)?;
29    let cache_arc: Arc<dyn crate::cache::Cache> = Arc::from(cache);
30
31    // Create document service
32    let doc_service = Arc::new(crate::tools::docs::DocService::new(cache_arc));
33
34    // Create tool registry
35    let registry = crate::tools::create_default_registry(&doc_service);
36
37    match tool {
38        "lookup_crate" => {
39            execute_lookup_crate(crate_name, version, format, &registry).await?;
40        }
41        "search_crates" => {
42            execute_search_crates(query, limit, format, &registry).await?;
43        }
44        "lookup_item" => {
45            execute_lookup_item(crate_name, item_path, version, format, &registry).await?;
46        }
47        "health_check" => {
48            execute_health_check(&registry).await?;
49        }
50        _ => {
51            return Err(format!("Unknown tool: {tool}").into());
52        }
53    }
54
55    println!("Tool test completed");
56    Ok(())
57}
58
59/// Execute `lookup_crate` tool
60async fn execute_lookup_crate(
61    crate_name: Option<&str>,
62    version: Option<&str>,
63    format: &str,
64    registry: &crate::tools::ToolRegistry,
65) -> Result<(), Box<dyn std::error::Error>> {
66    if let Some(name) = crate_name {
67        println!("Testing crate lookup: {name} (version: {version:?})");
68        println!("Output format: {format}");
69
70        // Prepare arguments
71        let mut arguments = serde_json::json!({
72            "crate_name": name,
73            "format": format
74        });
75
76        if let Some(v) = version {
77            arguments["version"] = serde_json::Value::String(v.to_string());
78        }
79
80        // Execute tool
81        match registry.execute_tool("lookup_crate", arguments).await {
82            Ok(result) => print_tool_result(&result),
83            Err(e) => eprintln!("Tool execution failed: {e}"),
84        }
85    } else {
86        return Err("lookup_crate requires --crate-name parameter".into());
87    }
88    Ok(())
89}
90
91/// Execute `search_crates` tool
92async fn execute_search_crates(
93    query: Option<&str>,
94    limit: u32,
95    format: &str,
96    registry: &crate::tools::ToolRegistry,
97) -> Result<(), Box<dyn std::error::Error>> {
98    if let Some(q) = query {
99        println!("Testing crate search: {q} (limit: {limit})");
100        println!("Output format: {format}");
101
102        // Prepare arguments
103        let arguments = serde_json::json!({
104            "query": q,
105            "limit": limit,
106            "format": format
107        });
108
109        // Execute tool
110        match registry.execute_tool("search_crates", arguments).await {
111            Ok(result) => print_tool_result(&result),
112            Err(e) => eprintln!("Tool execution failed: {e}"),
113        }
114    } else {
115        return Err("search_crates requires --query parameter".into());
116    }
117    Ok(())
118}
119
120/// Execute `lookup_item` tool
121async fn execute_lookup_item(
122    crate_name: Option<&str>,
123    item_path: Option<&str>,
124    version: Option<&str>,
125    format: &str,
126    registry: &crate::tools::ToolRegistry,
127) -> Result<(), Box<dyn std::error::Error>> {
128    if let (Some(name), Some(path)) = (crate_name, item_path) {
129        println!("Testing item lookup: {name}::{path} (version: {version:?})");
130        println!("Output format: {format}");
131
132        // Prepare arguments
133        let mut arguments = serde_json::json!({
134            "crate_name": name,
135            "itemPath": path,
136            "format": format
137        });
138
139        if let Some(v) = version {
140            arguments["version"] = serde_json::Value::String(v.to_string());
141        }
142
143        // Execute tool
144        match registry.execute_tool("lookup_item", arguments).await {
145            Ok(result) => print_tool_result(&result),
146            Err(e) => eprintln!("Tool execution failed: {e}"),
147        }
148    } else {
149        return Err("lookup_item requires --crate-name and --item-path parameters".into());
150    }
151    Ok(())
152}
153
154/// Execute `health_check` tool
155async fn execute_health_check(
156    registry: &crate::tools::ToolRegistry,
157) -> Result<(), Box<dyn std::error::Error>> {
158    println!("Testing health check");
159
160    // Prepare arguments
161    let arguments = serde_json::json!({
162        "check_type": "all",
163        "verbose": true
164    });
165
166    // Execute tool
167    match registry.execute_tool("health_check", arguments).await {
168        Ok(result) => print_tool_result(&result),
169        Err(e) => eprintln!("Tool execution failed: {e}"),
170    }
171    Ok(())
172}
173
174/// Print tool execution result
175fn print_tool_result(result: &rust_mcp_sdk::schema::CallToolResult) {
176    println!("Tool executed successfully:");
177    if let Some(content) = result.content.first() {
178        match content {
179            ContentBlock::TextContent(text_content) => {
180                println!("{}", text_content.text);
181            }
182            other => {
183                println!("Non-text content: {other:?}");
184            }
185        }
186    }
187}