From 8daa746da68a7dbb3e6bfe8f01b91f7d1d58f588 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 13 Jun 2020 13:16:25 -0400 Subject: [PATCH] Initial structure for the perform_math_operation function. --- js/test_cases/helpers_math/README.md | 5 ++ js/test_cases/helpers_math/input1.json | 4 +- js/test_cases/helpers_math/main.dust | 63 ++++++++++++++++++++-- src/renderer/renderer.rs | 73 +++++++++++++++++++++++++- 4 files changed, 138 insertions(+), 7 deletions(-) diff --git a/js/test_cases/helpers_math/README.md b/js/test_cases/helpers_math/README.md index 9984083..9ae12f0 100644 --- a/js/test_cases/helpers_math/README.md +++ b/js/test_cases/helpers_math/README.md @@ -2,3 +2,8 @@ Early termination ----------------- If the math helper has a body then it stops rendering conditionals after the first conditional that returns true. Rendering an else block does not cause early termination, but else blocks are rendered. + +Non-number values +----------------- + +If the math operation involves non-numbers, NaN is returned. diff --git a/js/test_cases/helpers_math/input1.json b/js/test_cases/helpers_math/input1.json index 77959bc..3b5727f 100644 --- a/js/test_cases/helpers_math/input1.json +++ b/js/test_cases/helpers_math/input1.json @@ -1,5 +1,7 @@ { "number_7": 7, "string_7": "7", - "string_cat": "cat" + "string_cat": "cat", + "add_operation": "add", + "a_operation": "a" } diff --git a/js/test_cases/helpers_math/main.dust b/js/test_cases/helpers_math/main.dust index 5108995..5559821 100644 --- a/js/test_cases/helpers_math/main.dust +++ b/js/test_cases/helpers_math/main.dust @@ -4,6 +4,7 @@ Bodiless math{~n} {@math key=number_7 method="add" operand="4" /}{~n} {@math key=string_7 method="add" operand="4" /}{~n} {@math key=string_cat method="add" operand="4" /}{~n} +{@math key=string_cat method="add" operand="foo" /}{~n} Math with body: dot reference{~n} ============================={~n} @@ -44,15 +45,67 @@ Math with body: standalone else block{~n} Math with body: early termination{~n} ============================={~n} {@math key="7" method="add" operand="4"} - {@eq value=11}math result is 11{:else}math result is not 11{/eq}{~n} - {@eq value=11}math result is 11{:else}math result is not 11{/eq}{~n} + {@eq value=11}math result is 11{~n}{:else}math result is not 11{~n}{/eq} + {@eq value=11}math result is 11{~n}{:else}math result is not 11{~n}{/eq} {/math} Math with body: early termination else block{~n} ============================================{~n} {@math key="7" method="add" operand="4"} - {@eq value=12}math result is 12{:else}math result is not 12{/eq}{~n} - {@eq value=11}math result is 11{:else}math result is not 11{/eq}{~n} - {@eq value=12}math result is 12{:else}math result is not 12{/eq}{~n} + {@eq value=12}math result is 12{~n}{:else}math result is not 12{~n}{/eq} + {@eq value=11}math result is 11{~n}{:else}math result is not 11{~n}{/eq} + {@eq value=12}math result is 12{~n}{:else}math result is not 12{~n}{/eq} {/math} + +Math with body: any{~n} +==================={~n} +{@math key="7" method="add" operand="4"} + {@eq value=10}math result is 10{~n}{:else}math result is not 10{~n}{/eq} + {@eq value=11}math result is 11{~n}{:else}math result is not 11{~n}{/eq} + {@eq value=12}math result is 12{~n}{:else}math result is not 12{~n}{/eq} + {@any}We found the value{~n}{/any} + {@none}We did not find the value{~n}{/none} +{/math} + +Math with body: none{~n} +===================={~n} +{@math key="7" method="add" operand="4"} + {@eq value=10}math result is 10{~n}{:else}math result is not 10{~n}{/eq} + {@eq value=12}math result is 12{~n}{:else}math result is not 12{~n}{/eq} + {@any}We found the value{~n}{/any} + {@none}We did not find the value{~n}{/none} +{/math} + +Math where method is a reference{~n} +================================{~n} +{@math key="7" method=add_operation operand="4" /}{~n} + +Math where method is a template{~n} +==============================={~n} +{@math key="7" method="{a_operation}dd" operand="4" /}{~n} + +Math where key is a template{~n} +============================{~n} +{@math key="{string_7}1" method="add" operand="4" /}{~n} + +Math where method is absent{~n} +============================{~n} +{@math key="7" operand="4" /}{~n} + +Math where method is missing{~n} +============================{~n} +{@math key="7" method=foobar operand="4" /}{~n} + +Math with unknown method{~n} +========================{~n} +{@math key="7" method="twirl" operand="4" /}{~n} + +Math with body where method is absent{~n} +===================================={~n} +{@math key="7" operand="4"} + {@eq value=12}math result is 12{~n}{:else}math result is not 12{~n}{/eq} + {@any}We found the value{~n}{/any} + {@none}We did not find the value{~n}{/none} + plain text not inside a tag{~n} +{/math} diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index b8104a7..1ad71c5 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -644,7 +644,32 @@ impl<'a> DustRenderer<'a> { } _ => return Ok("".to_owned()), }, - DustTag::DTHelperMath(parameterized_block) => {} + DustTag::DTHelperMath(parameterized_block) => { + let new_breadcrumbs = self.new_breadcrumbs_partial( + breadcrumbs, + breadcrumbs, + None, + ¶meterized_block.explicit_context, + ); + let new_breadcrumbs_ref = new_breadcrumbs.as_ref().unwrap_or(breadcrumbs); + let param_map = + ParametersContext::new(self, breadcrumbs, ¶meterized_block.params, None); + match ¶meterized_block.contents { + None => { + // TODO: math without body, calculate the value and render it + // Calculate the value + // Render + } + Some(_) => { + // TODO: math with body, calculate the value and use it like a select block + // Calculate the value + // Generate a ParametersContext with the result of the math operation as key + // calculate are_any_checks_true + // Generate a SelectContext + // render_maybe_body + } + } + } } Ok("".to_owned()) @@ -902,6 +927,52 @@ impl<'a> DustRenderer<'a> { _ => panic!("perform_comparison_check only implemented for comparison helpers (eq, ne, gt, gte, lt, lte)") } } + + /// Performs a math operation (add, subtract, multiply, divide, + /// mod, abs, floor, ceil) and returns the result or None if + /// nothing should be rendered. + fn performance_math_operation( + &'a self, + breadcrumbs: &'a Vec>, + math_parameters: &'a ParametersContext<'a>, + ) -> Option> { + let method = match self.tap(breadcrumbs, math_parameters, "method") { + None | Some(Err(_)) => return None, + Some(Ok(ice_result)) => ice_result, + }; + let method_rendered = match method.get_context_element_reference().render(&Vec::new()) { + Ok(text) => text, + Err(_) => return None, + }; + + let left_side = self.tap(breadcrumbs, math_parameters, "key"); + let right_side = self.tap(breadcrumbs, math_parameters, "operand"); + + let left_side_ce = left_side.as_ref().map(|maybe_ice| { + maybe_ice + .as_ref() + .map(|ice| ice.get_context_element_reference()) + }); + let right_side_ce = right_side.as_ref().map(|maybe_ice| { + maybe_ice + .as_ref() + .map(|ice| ice.get_context_element_reference()) + }); + + match method_rendered.as_str() { + "add" => todo!(), + "subtract" => todo!(), + "multiply" => todo!(), + "divide" => todo!(), + "mod" => todo!(), + "abs" => todo!(), + "floor" => todo!(), + "ceil" => todo!(), + _ => return None, + } + + todo!() + } } struct BlockContext<'a> {