1use serde_json::{json, Value};
7
8#[derive(Debug, Clone)]
10pub struct ToolParam {
11 pub name: String,
12 pub description: String,
13 pub param_type: ParamType,
14 pub required: bool,
15}
16
17#[derive(Debug, Clone)]
19pub enum ParamType {
20 String,
21 Integer,
22 Number,
23 Boolean,
24 Object,
25 Array,
26}
27
28impl ParamType {
29 pub fn to_json_type(&self) -> &'static str {
31 match self {
32 ParamType::String => "string",
33 ParamType::Integer => "integer",
34 ParamType::Number => "number",
35 ParamType::Boolean => "boolean",
36 ParamType::Object => "object",
37 ParamType::Array => "array",
38 }
39 }
40}
41
42pub type ToolHandler = fn(&Value) -> Result<Value, String>;
47
48pub struct Tool {
52 pub active: bool,
53 pub name: String,
54 pub description: String,
55 pub params: Vec<ToolParam>,
56 pub handler: ToolHandler,
57}
58
59impl Tool {
60 pub fn builder(name: &str, description: &str, active: bool) -> ToolBuilder {
70 ToolBuilder {
71 active,
72 name: name.to_string(),
73 description: description.to_string(),
74 params: Vec::new(),
75 }
76 }
77
78 pub fn to_json_schema(&self) -> Value {
93 let mut properties = serde_json::Map::new();
94 let mut required = Vec::new();
95
96 for param in &self.params {
97 properties.insert(
98 param.name.clone(),
99 json!({
100 "type": param.param_type.to_json_type(),
101 "description": param.description
102 })
103 );
104
105 if param.required {
106 required.push(param.name.clone());
107 }
108 }
109
110 json!({
111 "name": self.name,
112 "description": self.description,
113 "inputSchema": {
114 "type": "object",
115 "properties": properties,
116 "required": required
117 }
118 })
119 }
120}
121
122pub struct ToolBuilder {
124 active: bool,
125 name: String,
126 description: String,
127 params: Vec<ToolParam>,
128}
129
130impl ToolBuilder {
131 pub fn param_string(mut self, name: &str, description: &str, required: bool) -> Self {
138 self.params.push(ToolParam {
139 name: name.to_string(),
140 description: description.to_string(),
141 param_type: ParamType::String,
142 required,
143 });
144 self
145 }
146
147 pub fn param_i64(mut self, name: &str, description: &str, required: bool) -> Self {
149 self.params.push(ToolParam {
150 name: name.to_string(),
151 description: description.to_string(),
152 param_type: ParamType::Integer,
153 required,
154 });
155 self
156 }
157
158 pub fn param_f64(mut self, name: &str, description: &str, required: bool) -> Self {
160 self.params.push(ToolParam {
161 name: name.to_string(),
162 description: description.to_string(),
163 param_type: ParamType::Number,
164 required,
165 });
166 self
167 }
168
169 pub fn param_bool(mut self, name: &str, description: &str, required: bool) -> Self {
171 self.params.push(ToolParam {
172 name: name.to_string(),
173 description: description.to_string(),
174 param_type: ParamType::Boolean,
175 required,
176 });
177 self
178 }
179
180 pub fn param_object(mut self, name: &str, description: &str, required: bool) -> Self {
182 self.params.push(ToolParam {
183 name: name.to_string(),
184 description: description.to_string(),
185 param_type: ParamType::Object,
186 required,
187 });
188 self
189 }
190
191 pub fn param_array(mut self, name: &str, description: &str, required: bool) -> Self {
193 self.params.push(ToolParam {
194 name: name.to_string(),
195 description: description.to_string(),
196 param_type: ParamType::Array,
197 required,
198 });
199 self
200 }
201
202 pub fn handler(self, handler: ToolHandler) -> Tool {
206 Tool {
207 active: self.active,
208 name: self.name,
209 description: self.description,
210 params: self.params,
211 handler,
212 }
213 }
214}
215