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 name: String,
53 pub description: String,
54 pub params: Vec<ToolParam>,
55 pub handler: ToolHandler,
56}
57
58impl Tool {
59 pub fn builder(name: &str, description: &str) -> ToolBuilder {
69 ToolBuilder {
70 name: name.to_string(),
71 description: description.to_string(),
72 params: Vec::new(),
73 }
74 }
75
76 pub fn to_json_schema(&self) -> Value {
91 let mut properties = serde_json::Map::new();
92 let mut required = Vec::new();
93
94 for param in &self.params {
95 properties.insert(
96 param.name.clone(),
97 json!({
98 "type": param.param_type.to_json_type(),
99 "description": param.description
100 })
101 );
102
103 if param.required {
104 required.push(param.name.clone());
105 }
106 }
107
108 json!({
109 "name": self.name,
110 "description": self.description,
111 "inputSchema": {
112 "type": "object",
113 "properties": properties,
114 "required": required
115 }
116 })
117 }
118}
119
120pub struct ToolBuilder {
122 name: String,
123 description: String,
124 params: Vec<ToolParam>,
125}
126
127impl ToolBuilder {
128 pub fn param_string(mut self, name: &str, description: &str, required: bool) -> Self {
135 self.params.push(ToolParam {
136 name: name.to_string(),
137 description: description.to_string(),
138 param_type: ParamType::String,
139 required,
140 });
141 self
142 }
143
144 pub fn param_i64(mut self, name: &str, description: &str, required: bool) -> Self {
146 self.params.push(ToolParam {
147 name: name.to_string(),
148 description: description.to_string(),
149 param_type: ParamType::Integer,
150 required,
151 });
152 self
153 }
154
155 pub fn param_f64(mut self, name: &str, description: &str, required: bool) -> Self {
157 self.params.push(ToolParam {
158 name: name.to_string(),
159 description: description.to_string(),
160 param_type: ParamType::Number,
161 required,
162 });
163 self
164 }
165
166 pub fn param_bool(mut self, name: &str, description: &str, required: bool) -> Self {
168 self.params.push(ToolParam {
169 name: name.to_string(),
170 description: description.to_string(),
171 param_type: ParamType::Boolean,
172 required,
173 });
174 self
175 }
176
177 pub fn param_object(mut self, name: &str, description: &str, required: bool) -> Self {
179 self.params.push(ToolParam {
180 name: name.to_string(),
181 description: description.to_string(),
182 param_type: ParamType::Object,
183 required,
184 });
185 self
186 }
187
188 pub fn param_array(mut self, name: &str, description: &str, required: bool) -> Self {
190 self.params.push(ToolParam {
191 name: name.to_string(),
192 description: description.to_string(),
193 param_type: ParamType::Array,
194 required,
195 });
196 self
197 }
198
199 pub fn handler(self, handler: ToolHandler) -> Tool {
203 Tool {
204 name: self.name,
205 description: self.description,
206 params: self.params,
207 handler,
208 }
209 }
210}
211