diff --git a/src/template.rs b/src/template.rs index 8cffb9297..d9697b81b 100644 --- a/src/template.rs +++ b/src/template.rs @@ -288,11 +288,33 @@ impl Template { Parameter::Path(Path::new(param_span.as_str(), path_segs)) } Rule::literal => { - let s = param_span.as_str(); - if let Ok(json) = Json::from_str(s) { + // Parse the parameter as a JSON literal + let param_literal = it.next().unwrap(); + let json_result = match param_literal.as_rule() { + Rule::string_literal + if it.peek().unwrap().as_rule() == Rule::string_inner_single_quote => + { + // ...unless the parameter is a single-quoted string. + // In that case, transform it to a double-quoted string + // and then parse it as a JSON literal. + let string_inner_single_quote = it.next().unwrap(); + let double_quoted = format!( + "\"{}\"", + string_inner_single_quote + .as_str() + .replace("\\'", "'") + .replace('"', "\\\"") + ); + Json::from_str(&double_quoted) + } + _ => Json::from_str(param_span.as_str()), + }; + if let Ok(json) = json_result { Parameter::Literal(json) } else { - Parameter::Name(s.to_owned()) + return Err(TemplateError::of(TemplateErrorReason::InvalidParam( + param_span.as_str().to_owned(), + ))); } } Rule::subexpression => { diff --git a/tests/escape.rs b/tests/escape.rs index 4a737f5ce..2b9512290 100644 --- a/tests/escape.rs +++ b/tests/escape.rs @@ -27,19 +27,44 @@ fn test_string_no_escape_422() { handlebars_helper!(replace: |input: str, from: str, to: str| { input.replace(from, to) }); + handlebars_helper!(echo: |input: str| { + input + }); hbs.register_helper("replace", Box::new(replace)); + hbs.register_helper("echo", Box::new(echo)); assert_eq!( r#"some\ path"#, hbs.render_template(r#"{{replace "some/path" "/" "\\ " }}"#, &()) .unwrap() ); + assert_eq!( + r#"some\ path"#, + hbs.render_template(r#"{{replace 'some/path' '/' '\\ ' }}"#, &()) + .unwrap() + ); assert_eq!( r#"some\path"#, hbs.render_template(r#"{{replace "some/path" "/" "\\" }}"#, &()) .unwrap() ); + assert_eq!( + r#"some\path"#, + hbs.render_template(r#"{{replace 'some/path' '/' '\\' }}"#, &()) + .unwrap() + ); + + assert_eq!( + r#"double-quoted \ 'with' "nesting""#, + hbs.render_template(r#"{{echo "double-quoted \\ 'with' \"nesting\""}}"#, &()) + .unwrap() + ); + assert_eq!( + r#"single-quoted \ 'with' "nesting""#, + hbs.render_template(r#"{{echo 'single-quoted \\ \'with\' "nesting"'}}"#, &()) + .unwrap() + ); } #[test] diff --git a/tests/helper_macro.rs b/tests/helper_macro.rs index 4b055d6f4..f40ab778a 100644 --- a/tests/helper_macro.rs +++ b/tests/helper_macro.rs @@ -100,5 +100,10 @@ fn test_macro_helper() { ) .unwrap(), "false" - ) + ); + + assert_eq!( + hbs.render_template("{{tag 'html'}}", &()).unwrap(), + "<html>" + ); }