Skip to main content

soma_codemode/snippet/
resolve.rs

1use 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}