diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index f1434e6..75fee5a 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -970,12 +970,19 @@ impl<'a> DustRenderer<'a> { }) } + /// Performs a comparison (eq, ne, gt, gte, lt, lte) and returns + /// whether or not the comparison was true. + /// + /// Returns None in the special case that the "key" parameter did + /// not exist at all. This means that key was not in the original + /// dust template source, which is not the same as key referencing + /// a value which does not exist. fn perform_comparison_check( &'a self, tag: &'a DustTag, breadcrumbs: &'a Vec>, select_parameters: Option<&'a ParametersContext<'a>>, - ) -> bool { + ) -> Option { let param_map = match tag { DustTag::DTHelperEquals(parameterized_block) | DustTag::DTHelperNotEquals(parameterized_block) @@ -985,7 +992,54 @@ impl<'a> DustRenderer<'a> { | DustTag::DTHelperLessThanOrEquals(parameterized_block) => ParametersContext::new(self, breadcrumbs, ¶meterized_block.params, select_parameters), _ => panic!("perform_comparison_check only implemented for comparison helpers (eq, ne, gt, gte, lt, lte)") }; - todo!() + + let left_side = self.tap(breadcrumbs, ¶m_map, "key"); + let right_side = self.tap(breadcrumbs, ¶m_map, "value"); + + 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()) + }); + if left_side_ce.is_none() { + // If key did not exist at all, return None + return None; + } + match tag { + // Special case: when comparing two RVPaths, if the path + // points to the same value then they are equal. This is + // particularly important for objects which compare memory + // locations rather than contents (javascript object + // equality). + DustTag::DTHelperEquals(_) => Some(Self::are_paths_identical(&left_side_ce, &right_side_ce) + || left_side_ce.unwrap_or(Err(&WalkError::CantWalk)) + == right_side_ce.unwrap_or(Err(&WalkError::CantWalk))), + DustTag::DTHelperNotEquals(_) => Some(!Self::are_paths_identical(&left_side_ce, &right_side_ce) + && left_side_ce.unwrap_or(Err(&WalkError::CantWalk)) + != right_side_ce.unwrap_or(Err(&WalkError::CantWalk))), + DustTag::DTHelperGreaterThan(_) => Some(match (left_side_ce, right_side_ce) { + (Some(Ok(left_value)), Some(Ok(right_value))) if left_value > right_value => true, + _ => false + }), + DustTag::DTHelperLessThan(_) => Some(match (left_side_ce, right_side_ce) { + (Some(Ok(left_value)), Some(Ok(right_value))) if left_value < right_value => true, + _ => false + }), + DustTag::DTHelperGreaterThanOrEquals(_) => Some(match (left_side_ce, right_side_ce) { + (Some(Ok(left_value)), Some(Ok(right_value))) if left_value >= right_value => true, + _ => false + }), + DustTag::DTHelperLessThanOrEquals(_) => Some(match (left_side_ce, right_side_ce) { + (Some(Ok(left_value)), Some(Ok(right_value))) if left_value <= right_value => true, + _ => false + }), + _ => panic!("perform_comparison_check only implemented for comparison helpers (eq, ne, gt, gte, lt, lte)") + } } }