Skip to content

Commit

Permalink
Expand merge helper scopes (#467)
Browse files Browse the repository at this point in the history
* Expand merge to support more scope types

* Fix format

---------

Co-authored-by: Collins Muriuki <[email protected]>
  • Loading branch information
guillemcordoba and c12i authored Feb 24, 2025
1 parent e51aff1 commit f90da9d
Showing 1 changed file with 65 additions and 16 deletions.
81 changes: 65 additions & 16 deletions src/templates/helpers/merge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,32 @@ pub fn get_scope_open_and_close_char_indexes(
"Given scope opener not found in the given parameter",
))?;

let Some(open_scope_character) = scope_opener.chars().last() else {
return Err(RenderError::new(
"match_scope's first parameter cannot be an empty string",
));
};
let close_scope_character = match open_scope_character {
'{' => '}',
'[' => ']',
'(' => ')',
'<' => '>',
_ => Err(RenderError::new(
"Last character for the first match_scope parameter was not recognized as a scope opener character."
))?
};

index = index + scope_opener.len() - 1;
let scope_opener_index = index;
let mut scope_count = 1;

while scope_count > 0 {
index += 1;
match text.chars().nth(index) {
Some('{') => {
Some(c) if c == open_scope_character => {
scope_count += 1;
}
Some('}') => {
Some(c) if c == close_scope_character => {
scope_count -= 1;
}
None => {
Expand Down Expand Up @@ -150,9 +165,9 @@ impl HelperDef for MatchScope {
rc: &mut RenderContext<'reg, 'rc>,
_out: &mut dyn Output,
) -> HelperResult {
let t = h
.template()
.ok_or(RenderError::new("merge helper cannot have empty content"))?;
let t = h.template().ok_or(RenderError::new(
"match_scope helper cannot have empty content",
))?;

let mut data = rc
.context()
Expand All @@ -170,10 +185,12 @@ impl HelperDef for MatchScope {

let scope_opener = h
.param(0)
.ok_or(RenderError::new("merge helper needs 1 parameter"))?
.ok_or(RenderError::new("match_scope helper needs 1 parameter"))?
.value()
.as_str()
.ok_or(RenderError::new("merge's first parameter must be a string"))?
.ok_or(RenderError::new(
"match_scope's first parameter must be a string",
))?
.to_string();

let (scope_opener_index, scope_close_index) =
Expand Down Expand Up @@ -239,6 +256,14 @@ mod tests {
use handlebars::Handlebars;
use serde_json::json;

fn build_handlebars<'a>() -> Handlebars<'a> {
let mut h = Handlebars::new();
h.register_escape_fn(handlebars::no_escape);

let h = register_merge(h);
h
}

#[test]
fn test_get_scope_open_and_close_char_indexes() {
let text = String::from("const s = {};");
Expand All @@ -253,9 +278,7 @@ mod tests {

#[test]
fn test_merge_match_scope_empty() {
let h = Handlebars::new();

let h = register_merge(h);
let h = build_handlebars();

let code = r#"
class A {
Expand All @@ -277,9 +300,7 @@ mod tests {

#[test]
fn test_merge_match_scope_simple() {
let h = Handlebars::new();

let h = register_merge(h);
let h = build_handlebars();

let code = r#"class A {
// Multiline
Expand Down Expand Up @@ -314,10 +335,38 @@ class A {
}

#[test]
fn test_merge_match_scope() {
let h = Handlebars::new();
fn test_merge_match_scope_simple_with_array_scopes() {
let h = build_handlebars();

let h = register_merge(h);
let code = r#"const a = [
1,
];
"#;
let value = json!({"previous_file_content": code});
let context = Context::from(value);
let template = r#"
{{#merge previous_file_content}}
{{#match_scope "const a = ["}}
{{previous_scope_content}}
2,
{{/match_scope}}
{{/merge}}
"#;

assert_eq!(
h.render_template_with_context(template, &context).unwrap(),
r#"
const a = [
1,
2,
];
"#,
);
}

#[test]
fn test_merge_match_scope() {
let h = build_handlebars();

let code = r#"export class A {
nestedFn1() {
Expand Down

0 comments on commit f90da9d

Please sign in to comment.