stepflow_action/
string_template.rs1use std::collections::HashMap;
2
3
4pub fn render_template<ES>(escaped_template: &ES, params: HashMap<&'static str, ES>) -> String
7 where ES: AsRef<str>
8{
9 let mut escaped_template: &str = escaped_template.as_ref();
10 let mut result = String::new();
11
12 for (k, v) in params {
13 let mut full_key = String::with_capacity(k.len() + 4 );
14 full_key.push_str("{{");
15 full_key.push_str(&k[..]);
16 full_key.push_str("}}");
17
18 result = escaped_template.replace(&full_key[..], v.as_ref());
19 escaped_template = &result[..];
20 }
21 result
22}
23
24pub trait EscapedString : AsRef<str> + std::fmt::Debug + Send + Sync + 'static {
25 fn from_unescaped(unescaped_str: &str) -> Self;
26 fn already_escaped(escaped_str: String) -> Self;
27}
28
29#[derive(Debug)]
30pub struct HtmlEscapedString(String);
31impl EscapedString for HtmlEscapedString {
32 fn from_unescaped(unescaped_str: &str) -> Self {
33 HtmlEscapedString(htmlescape::encode_attribute(unescaped_str))
34 }
35 fn already_escaped(escaped_str: String) -> Self {
36 HtmlEscapedString(escaped_str)
37 }
38}
39
40impl HtmlEscapedString {
41 pub fn len(&self) -> usize {
42 self.0.len()
43 }
44}
45
46impl AsRef<str> for HtmlEscapedString {
47 fn as_ref(&self) -> &str {
48 &(self.0)[..]
49 }
50}
51
52#[derive(Debug)]
53pub struct UriEscapedString(String);
54impl EscapedString for UriEscapedString {
55 fn from_unescaped(unescaped_str: &str) -> Self {
56 UriEscapedString(urlencoding::encode(unescaped_str))
57 }
58 fn already_escaped(escaped_str: String) -> Self {
59 UriEscapedString(escaped_str)
60 }
61}
62impl AsRef<str> for UriEscapedString {
63 fn as_ref(&self) -> &str {
64 &(self.0)[..]
65 }
66}
67
68
69#[cfg(test)]
70mod tests {
71 use std::collections::HashMap;
72 use super::render_template;
73
74 struct Escaped(&'static str);
75 impl AsRef<str> for Escaped {
76 fn as_ref(&self) -> &str {
77 self.0
78 }
79 }
80
81 #[test]
82 fn handlebars_basic() {
83 let mut params = HashMap::new();
84 params.insert("name", Escaped("bob"));
85 params.insert("value", Escaped("myvalue"));
86 let output = render_template::<Escaped>(&Escaped("name{{name}}, value{{value}}"), params);
87 assert_eq!(output, "namebob, valuemyvalue");
88 }
89}