soma_codemode/snippet/
resolve.rs1use serde_json::{Map, Value};
2
3use crate::ToolError;
4
5use super::store::{SnippetInfo, SnippetInputType};
6
7pub fn bind_snippet_input(info: &SnippetInfo, input: Value) -> Result<Value, ToolError> {
8 let object = input.as_object().cloned().unwrap_or_default();
9 let mut bound = Map::new();
10 for (name, spec) in &info.inputs {
11 match object.get(name) {
12 Some(value) if input_type_matches(value, &spec.input_type) => {
13 bound.insert(name.clone(), value.clone());
14 }
15 Some(_) => {
16 return Err(ToolError::InvalidParam {
17 message: format!("snippet input `{name}` has wrong type"),
18 param: name.clone(),
19 });
20 }
21 None if spec.required => {
22 return Err(ToolError::MissingParam {
23 message: format!("snippet input `{name}` is required"),
24 param: name.clone(),
25 });
26 }
27 None => {}
28 }
29 }
30 Ok(Value::Object(bound))
31}
32
33fn input_type_matches(value: &Value, input_type: &SnippetInputType) -> bool {
34 match input_type {
35 SnippetInputType::String => value.is_string(),
36 SnippetInputType::Number => value.is_number(),
37 SnippetInputType::Boolean => value.is_boolean(),
38 SnippetInputType::Json => true,
39 }
40}