use std::collections::HashMap;
use anyhow::{anyhow, Result};
pub type VarsMap = HashMap<String, String>;
pub fn expand_var(src: &str, key: &str, value: &str) -> String {
let from = format!("${{{}}}", key);
src.replace(&from, value)
}
pub fn expand_vars(src: &str, vars: &VarsMap) -> Result<String> {
let mut dst = src.to_string();
for (name, value) in vars.iter() {
dst = expand_var(&dst, name, value);
}
if dst.contains("${") {
return Err(anyhow!("'{dst}' contains unknown variables (original: '{src}'). It's possible Clyde needs to be updated."));
}
Ok(dst)
}
#[cfg(test)]
mod tests {
use super::*;
fn _test_expand_var(src: &str, key: &str, value: &str, expected: &str) {
let result = expand_var(&src, &key, &value);
assert_eq!(result, expected);
}
#[test]
fn test_expand_var() {
_test_expand_var("foo${exe}", "exe", ".exe", "foo.exe");
_test_expand_var("${dir}/bar", "dir", "some/where", "some/where/bar");
}
#[test]
fn test_expand_vars() {
let map = VarsMap::from([
("exe".into(), ".exe".into()),
("dir".into(), "some/where".into()),
]);
let result = expand_vars("${dir}/foo${exe}", &map).unwrap();
assert_eq!(result, "some/where/foo.exe");
}
#[test]
fn expand_vars_should_fail_on_unknown_vars() {
let map = VarsMap::from([("exe".into(), ".exe".into())]);
let result = expand_vars("foo${ex}", &map);
assert!(result.is_err());
}
}