1use std::any::Any;
2use std::collections::HashMap;
3use lazy_regex::regex;
4
5#[macro_export]
22macro_rules! string_args {
23 (@single $($x:tt)*) => (());
24 (@count $($rest:expr),*) => (<[()]>::len(&[$(string_args!(@single $rest)),*]));
25
26 ($($key:expr => $value:expr,)+) => { string_args!($($key => $value),+) };
27 ($($key:expr => $value:expr),*) => {
28 {
29 let r_cap = string_args!(@count $($key),*);
30 let mut r_map = HashMap::<String, Box<dyn Any>>::with_capacity(r_cap);
31 $(
32 let _ = r_map.insert($key.to_string(), Box::new($value));
33 )*
34 r_map
35 }
36 };
37}
38
39pub fn apply(base: impl AsRef<str>, vars: &HashMap<String, Box<dyn Any>>, convert: fn(arg: &Box<dyn Any>) -> String) -> String {
40 regex!(r"\$(\$|[A-Za-z0-9]+)").replace_all(base.as_ref(), |s: ®ex::Captures<'_>| {
41 let s = s.get(0).unwrap().as_str();
42 if s == "$$" {
43 "$".to_owned()
44 } else {
45 let v = vars.get(&s.to_string().replace("$", ""));
46 if let Some(v) = v { convert(v) } else { "None".to_owned() }
47 }
48 }).as_ref().to_string()
49}