1use std::collections::HashMap;
2use std::hash::BuildHasher;
3
4use regex::{Captures, Regex};
5
6pub fn substitute_parameters<S: BuildHasher>(
9 template: &str,
10 arguments: &Option<HashMap<String, String, S>>,
11) -> String {
12 let Ok(regex) = Regex::new(r"\$(\w+)") else {
13 return template.to_string();
14 };
15
16 arguments
17 .as_ref()
18 .map(|args| {
19 regex
20 .replace_all(template, |caps: &Captures| {
21 let text = caps[0].to_string();
22 let param_name = &caps[1];
23 args.get(param_name).cloned().unwrap_or(text)
24 })
25 .to_string()
26 })
27 .unwrap_or(template.to_string())
28}
29
30#[cfg(test)]
31mod tests {
32 use super::*;
33
34 #[test]
35 fn test_substitute_named_parameters() {
36 let template = "Review this $language code in $framework";
37 let args = HashMap::from([
38 ("language".to_string(), "Rust".to_string()),
39 ("framework".to_string(), "Actix".to_string()),
40 ]);
41
42 let result = substitute_parameters(template, &Some(args));
43 assert_eq!(result, "Review this Rust code in Actix");
44 }
45
46 #[test]
47 fn test_no_arguments() {
48 let template = "Hello $name, welcome to $project. Today is $day";
49 let none: Option<HashMap<String, String>> = None;
50 let result = substitute_parameters(template, &none);
51 assert_eq!(result, "Hello $name, welcome to $project. Today is $day");
52 }
53
54 #[test]
55 fn test_missing_parameter() {
56 let template = "Language: $language, Framework: $framework, Database: $database";
57 let args = HashMap::from([
58 ("language".to_string(), "Rust".to_string()),
59 ("framework".to_string(), "Actix".to_string()),
60 ]);
61
62 let result = substitute_parameters(template, &Some(args));
63 assert_eq!(
64 result,
65 "Language: Rust, Framework: Actix, Database: $database"
66 );
67 }
68
69 #[test]
70 fn test_empty_arguments() {
71 let template = "Process $input with $config";
72 let args = HashMap::new();
73 let result = substitute_parameters(template, &Some(args));
74 assert_eq!(result, "Process $input with $config");
75 }
76
77 #[test]
78 fn test_no_parameters_in_template() {
79 let template = "Just a plain string without parameters";
80 let args = HashMap::from([("unused".to_string(), "value".to_string())]);
81 let result = substitute_parameters(template, &Some(args));
82 assert_eq!(result, "Just a plain string without parameters");
83 }
84}