1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct Tool {
7 pub name: String,
8 pub description: String,
9 pub parameters: serde_json::Value,
10}
11
12pub fn available_tools() -> Vec<Tool> {
14 vec![
15 Tool {
16 name: "get_issues".to_string(),
17 description: "Get issues from configured git providers".to_string(),
18 parameters: serde_json::json!({
19 "type": "object",
20 "properties": {
21 "state": {
22 "type": "string",
23 "enum": ["open", "closed", "all"],
24 "description": "Filter by issue state"
25 }
26 }
27 }),
28 },
29 Tool {
30 name: "get_merge_requests".to_string(),
31 description: "Get merge requests / pull requests from configured git providers"
32 .to_string(),
33 parameters: serde_json::json!({
34 "type": "object",
35 "properties": {
36 "state": {
37 "type": "string",
38 "enum": ["open", "closed", "merged", "all"],
39 "description": "Filter by MR/PR state"
40 }
41 }
42 }),
43 },
44 ]
45}
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50
51 #[test]
52 fn test_available_tools_not_empty() {
53 let tools = available_tools();
54 assert!(!tools.is_empty(), "should have at least one tool");
55 }
56
57 #[test]
58 fn test_available_tools_contain_expected_names() {
59 let tools = available_tools();
60 let names: Vec<&str> = tools.iter().map(|t| t.name.as_str()).collect();
61 assert!(names.contains(&"get_issues"), "missing get_issues tool");
62 assert!(
63 names.contains(&"get_merge_requests"),
64 "missing get_merge_requests tool"
65 );
66 }
67
68 #[test]
69 fn test_available_tools_have_descriptions() {
70 let tools = available_tools();
71 for tool in &tools {
72 assert!(
73 !tool.description.is_empty(),
74 "tool '{}' has empty description",
75 tool.name
76 );
77 }
78 }
79
80 #[test]
81 fn test_available_tools_have_valid_parameters() {
82 let tools = available_tools();
83 for tool in &tools {
84 assert_eq!(
85 tool.parameters["type"], "object",
86 "tool '{}' parameters should be object type",
87 tool.name
88 );
89 assert!(
90 tool.parameters["properties"].is_object(),
91 "tool '{}' should have properties object",
92 tool.name
93 );
94 }
95 }
96
97 #[test]
98 fn test_tool_serialization_roundtrip() {
99 let tools = available_tools();
100 let json = serde_json::to_string(&tools).unwrap();
101 let parsed: Vec<Tool> = serde_json::from_str(&json).unwrap();
102 assert_eq!(parsed.len(), tools.len());
103 let parsed_names: Vec<&str> = parsed.iter().map(|t| t.name.as_str()).collect();
104 for tool in &tools {
105 assert!(parsed_names.contains(&tool.name.as_str()));
106 }
107 }
108}