Skip to main content

butterflow_models/
variable.rs

1use regex::Regex;
2use serde_json::Value;
3use std::collections::HashMap;
4
5use crate::error::Error;
6use crate::Result;
7
8/// Resolve variables in a string
9pub fn resolve_variables(
10    input: &str,
11    params: &HashMap<String, String>,
12    state: &HashMap<String, Value>,
13    matrix_values: Option<&HashMap<String, Value>>,
14) -> Result<String> {
15    let re = Regex::new(r"\$\{\{([^}]+)\}\}").unwrap();
16    let mut result = input.to_string();
17
18    for captures in re.captures_iter(input) {
19        let full_match = captures.get(0).unwrap().as_str();
20        let inner = captures.get(1).unwrap().as_str();
21
22        let replacement =
23            // First check if it's a direct matrix value
24            if matrix_values.is_some_and(|matrix_values| matrix_values.contains_key(inner)) {
25                serde_json::to_string(matrix_values.unwrap().get(inner).unwrap()).unwrap()
26            } else if let Some(name) = inner.strip_prefix("params.") {
27                params.get(name).cloned().ok_or_else(|| {
28                    Error::VariableResolution(format!("Parameter not found: {}", name))
29                })?
30            } else if let Some(name) = inner.strip_prefix("state.") {
31                let value = state.get(name).ok_or_else(|| {
32                    Error::VariableResolution(format!("State value not found: {}", name))
33                })?;
34                serde_json::to_string(value).unwrap()
35            } else {
36                return Err(Error::VariableResolution(format!(
37                    "Unknown variable type: {}",
38                    inner
39                )));
40            };
41
42        result = result.replace(full_match, &replacement);
43    }
44
45    Ok(result)
46}