diff --git a/js/test_cases/helpers_first/input1.json b/js/test_cases/helpers_first/input1.json new file mode 100644 index 0000000..f5fc911 --- /dev/null +++ b/js/test_cases/helpers_first/input1.json @@ -0,0 +1,23 @@ +{ + "people": [ + { + "name": "Alice", + "pet": "cat" + }, + { + "name": "Bob", + "pet": "dog" + }, + { + "name": "Chris", + "pet": "lizard" + } + ], + "toys": [ + "ball", + "bone" + ], + "scalar": 7, + "name": "global name", + "pet": "global pet" +} diff --git a/js/test_cases/helpers_first/main.dust b/js/test_cases/helpers_first/main.dust new file mode 100644 index 0000000..a7b4e1d --- /dev/null +++ b/js/test_cases/helpers_first/main.dust @@ -0,0 +1,29 @@ +Tags inside a first{~n} +==================={~n} +{#people} + {name}{@first petname="fluffy"},{pet}{petname}{/first} +{/people}{~n} + +first inside a scalar{~n} +====================={~n} +{#scalar} + {name}{@first petname="fluffy"},{pet}{petname}{/first} +{/scalar}{~n} + +Nested first inside another non-array section{~n} +============================================={~n} +{#people} + {#toys} + {name}'s pet {pet} plays with a {.}{@first}, {/first} + {/toys} +{/people}{~n} + +Else block inside a first{~n} +========================={~n} +{#people} + {name}{@first},{pet}{petname}{:else}elseblock{/first} +{/people}{~n} + +Sep outside any section{~n} +======================={~n} +{@first}first is printed outside any section{/first} diff --git a/js/test_cases/helpers_last/input1.json b/js/test_cases/helpers_last/input1.json new file mode 100644 index 0000000..f5fc911 --- /dev/null +++ b/js/test_cases/helpers_last/input1.json @@ -0,0 +1,23 @@ +{ + "people": [ + { + "name": "Alice", + "pet": "cat" + }, + { + "name": "Bob", + "pet": "dog" + }, + { + "name": "Chris", + "pet": "lizard" + } + ], + "toys": [ + "ball", + "bone" + ], + "scalar": 7, + "name": "global name", + "pet": "global pet" +} diff --git a/js/test_cases/helpers_last/main.dust b/js/test_cases/helpers_last/main.dust new file mode 100644 index 0000000..5b6cfdd --- /dev/null +++ b/js/test_cases/helpers_last/main.dust @@ -0,0 +1,29 @@ +Tags inside a last{~n} +=================={~n} +{#people} + {name}{@last petname="fluffy"},{pet}{petname}{/last} +{/people}{~n} + +last inside a scalar{~n} +===================={~n} +{#scalar} + {name}{@last petname="fluffy"},{pet}{petname}{/last} +{/scalar}{~n} + +Nested last inside another non-array section{~n} +============================================{~n} +{#people} + {#toys} + {name}'s pet {pet} plays with a {.}{@last}, {/last} + {/toys} +{/people}{~n} + +Else block inside a last{~n} +========================{~n} +{#people} + {name}{@last},{pet}{petname}{:else}elseblock{/last} +{/people}{~n} + +Sep outside any section{~n} +======================={~n} +{@last}last is printed outside any section{/last} diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 61f7904..956dace 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -694,8 +694,90 @@ impl<'a> DustRenderer<'a> { } } } - DustTag::DTHelperFirst(parameterized_block) => {} - DustTag::DTHelperLast(parameterized_block) => {} + DustTag::DTHelperFirst(parameterized_block) => { + let new_breadcrumbs = self.new_breadcrumbs_partial( + breadcrumbs, + breadcrumbs, + None, + ¶meterized_block.explicit_context, + ); + + let index = self.get(breadcrumbs, &vec!["$idx"]); + let len = self.get(breadcrumbs, &vec!["$len"]); + match (index, len) { + (Err(_), _) | (_, Err(_)) => return Ok("".to_owned()), + (Ok(index_resolved), Ok(len_resolved)) => { + // Iteration contexts use OwnedLiteral::LPositiveinteger + let index_cast = index_resolved + .get_context_element_reference() + .to_any() + .downcast_ref::(); + let len_cast = len_resolved + .get_context_element_reference() + .to_any() + .downcast_ref::(); + match (index_cast, len_cast) { + ( + Some(OwnedLiteral::LPositiveInteger(index_number)), + Some(OwnedLiteral::LPositiveInteger(len_number)), + ) => { + if *index_number != 0 { + return Ok("".to_owned()); + } else { + return self.render_maybe_body( + ¶meterized_block.contents, + new_breadcrumbs.as_ref().unwrap_or(breadcrumbs), + blocks, + ); + } + } + _ => return Ok("".to_owned()), + } + } + } + } + DustTag::DTHelperLast(parameterized_block) => { + let new_breadcrumbs = self.new_breadcrumbs_partial( + breadcrumbs, + breadcrumbs, + None, + ¶meterized_block.explicit_context, + ); + + let index = self.get(breadcrumbs, &vec!["$idx"]); + let len = self.get(breadcrumbs, &vec!["$len"]); + match (index, len) { + (Err(_), _) | (_, Err(_)) => return Ok("".to_owned()), + (Ok(index_resolved), Ok(len_resolved)) => { + // Iteration contexts use OwnedLiteral::LPositiveinteger + let index_cast = index_resolved + .get_context_element_reference() + .to_any() + .downcast_ref::(); + let len_cast = len_resolved + .get_context_element_reference() + .to_any() + .downcast_ref::(); + match (index_cast, len_cast) { + ( + Some(OwnedLiteral::LPositiveInteger(index_number)), + Some(OwnedLiteral::LPositiveInteger(len_number)), + ) => { + if *index_number != len_number - 1 { + return Ok("".to_owned()); + } else { + return self.render_maybe_body( + ¶meterized_block.contents, + new_breadcrumbs.as_ref().unwrap_or(breadcrumbs), + blocks, + ); + } + } + _ => return Ok("".to_owned()), + } + } + } + } } Ok("".to_owned())