use crate::error::{MainError, MainResult};
use regex::Regex;
use std::collections::HashMap;
pub fn expand(src: &str, subs: &HashMap<&str, &str>) -> MainResult<String> {
let re_sub = Regex::new(r"#\{([A-Za-z_][A-Za-z0-9_]*)}").unwrap();
let sub_size = subs.values().map(|v| v.len()).sum::<usize>();
let est_size = src.len() + sub_size;
let mut anchor = 0;
let mut result = String::with_capacity(est_size);
for m in re_sub.captures_iter(src) {
let (m_start, m_end) = {
let m_0 = m.get(0).unwrap();
(m_0.start(), m_0.end())
};
let prior_slice = anchor..m_start;
anchor = m_end;
result.push_str(&src[prior_slice]);
let sub_name = m.get(1).unwrap().as_str();
match subs.get(sub_name) {
Some(s) => result.push_str(s),
None => {
return Err(MainError::OtherOwned(format!(
"substitution `{}` in template is unknown",
sub_name
)))
}
}
}
result.push_str(&src[anchor..]);
Ok(result)
}