diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs
index cd83681..dc190dc 100644
--- a/src/renderer/renderer.rs
+++ b/src/renderer/renderer.rs
@@ -77,6 +77,18 @@ impl<'a> DustRenderer<'a> {
self.render_body(&main_template.contents, breadcrumbs, &new_blocks)
}
+ fn render_maybe_body(
+ &'a self,
+ body: &'a Option
,
+ breadcrumbs: &Vec<&'a dyn ContextElement>,
+ blocks: &'a InlinePartialTreeElement<'a>,
+ ) -> Result {
+ match body {
+ None => Ok("".to_owned()),
+ Some(body) => Ok(self.render_body(body, breadcrumbs, blocks)?),
+ }
+ }
+
fn render_body(
&'a self,
body: &'a Body,
@@ -130,16 +142,13 @@ impl<'a> DustRenderer<'a> {
}
DustTag::DTSection(container) => {
let val = walk_path(breadcrumbs, &container.path.keys);
- let loop_elements: Vec<&dyn ContextElement> = self.get_loop_elements(val);
+ let loop_elements: Vec<&dyn ContextElement> = Self::get_loop_elements(val);
if loop_elements.is_empty() {
// Oddly enough if the value is falsey (like
// an empty array or null), Dust uses the
// original context before walking the path as
// the context for rendering the else block
- return match &container.else_contents {
- Some(body) => self.render_body(&body, breadcrumbs, blocks),
- None => Ok("".to_owned()),
- };
+ return self.render_maybe_body(&container.else_contents, breadcrumbs, blocks);
} else {
match &container.contents {
None => return Ok("".to_owned()),
@@ -160,33 +169,21 @@ impl<'a> DustRenderer<'a> {
}
DustTag::DTExists(container) => {
let val = walk_path(breadcrumbs, &container.path.keys);
- let loop_elements: Vec<&dyn ContextElement> = self.get_loop_elements(val);
- if loop_elements.is_empty() {
- return match &container.else_contents {
- Some(body) => self.render_body(&body, breadcrumbs, blocks),
- None => Ok("".to_owned()),
- };
+ let loop_elements: Vec<&dyn ContextElement> = Self::get_loop_elements(val);
+ return if loop_elements.is_empty() {
+ self.render_maybe_body(&container.else_contents, breadcrumbs, blocks)
} else {
- return match &container.contents {
- None => Ok("".to_owned()),
- Some(body) => self.render_body(&body, breadcrumbs, blocks),
- };
- }
+ self.render_maybe_body(&container.contents, breadcrumbs, blocks)
+ };
}
DustTag::DTNotExists(container) => {
let val = walk_path(breadcrumbs, &container.path.keys);
- let loop_elements: Vec<&dyn ContextElement> = self.get_loop_elements(val);
- if !loop_elements.is_empty() {
- return match &container.else_contents {
- Some(body) => self.render_body(&body, breadcrumbs, blocks),
- None => Ok("".to_owned()),
- };
+ let loop_elements: Vec<&dyn ContextElement> = Self::get_loop_elements(val);
+ return if !loop_elements.is_empty() {
+ self.render_maybe_body(&container.else_contents, breadcrumbs, blocks)
} else {
- return match &container.contents {
- None => Ok("".to_owned()),
- Some(body) => self.render_body(&body, breadcrumbs, blocks),
- };
- }
+ self.render_maybe_body(&container.contents, breadcrumbs, blocks)
+ };
}
DustTag::DTPartial(partial) => {
if partial.params.is_empty() {
@@ -202,34 +199,19 @@ impl<'a> DustRenderer<'a> {
return Ok(rendered_content);
}
}
- DustTag::DTInlinePartial(named_block) => {
+ DustTag::DTInlinePartial(_named_block) => {
// Inline partials are blank during rendering (they get injected into blocks)
return Ok("".to_owned());
}
DustTag::DTBlock(named_block) => {
- match blocks.get_block(named_block.name) {
- None => match &named_block.contents {
- None => return Ok("".to_owned()),
- Some(body) => {
- let rendered_content = self.render_body(body, breadcrumbs, blocks)?;
- return Ok(rendered_content);
- }
- },
- Some(interior) => match interior {
- None => return Ok("".to_owned()),
- Some(body) => {
- let rendered_content = self.render_body(body, breadcrumbs, blocks)?;
- return Ok(rendered_content);
- }
- },
+ return match blocks.get_block(named_block.name) {
+ None => self.render_maybe_body(&named_block.contents, breadcrumbs, blocks),
+ Some(interior) => self.render_maybe_body(interior, breadcrumbs, blocks),
};
}
DustTag::DTHelperEquals(parameterized_block) => {
- let param_map: HashMap<&str, &RValue<'a>> = parameterized_block
- .params
- .iter()
- .map(|pair: &KVPair<'a>| (pair.key, &pair.value))
- .collect();
+ let param_map: HashMap<&str, &RValue<'a>> =
+ Self::get_rval_map(¶meterized_block.params);
// Special case: when comparing two RVPaths, if the
// path is equal then dust assumes the values are
// equal (otherwise, non-scalar values are
@@ -244,47 +226,31 @@ impl<'a> DustRenderer<'a> {
};
}
- let left_side: Result<&dyn ContextElement, WalkError> = match param_map.get("key") {
- None => return Ok("".to_owned()),
- Some(rval) => match rval {
- RValue::RVString(text) => Ok(text),
- RValue::RVPath(path) => walk_path(breadcrumbs, &path.keys),
- RValue::RVPositiveInteger(num) => Ok(num),
- },
- };
- let right_side: Result<&dyn ContextElement, WalkError> =
- match param_map.get("value") {
- None => Err(WalkError::CantWalk),
- Some(rval) => match rval {
- RValue::RVString(text) => Ok(text),
- RValue::RVPath(path) => walk_path(breadcrumbs, &path.keys),
- RValue::RVPositiveInteger(num) => Ok(num),
- },
+ let left_side: Result<&dyn ContextElement, WalkError> =
+ match Self::get_rval(breadcrumbs, ¶m_map, "key") {
+ None => return Ok("".to_owned()),
+ Some(res) => res,
};
+ let right_side: Result<&dyn ContextElement, WalkError> =
+ Self::get_rval(breadcrumbs, ¶m_map, "value")
+ .unwrap_or(Err(WalkError::CantWalk));
if left_side == right_side {
- match ¶meterized_block.contents {
- None => return Ok("".to_owned()),
- Some(body) => {
- let rendered_content = self.render_body(body, breadcrumbs, blocks)?;
- return Ok(rendered_content);
- }
- }
+ return self.render_maybe_body(
+ ¶meterized_block.contents,
+ breadcrumbs,
+ blocks,
+ );
} else {
- match ¶meterized_block.else_contents {
- None => return Ok("".to_owned()),
- Some(body) => {
- let rendered_content = self.render_body(body, breadcrumbs, blocks)?;
- return Ok(rendered_content);
- }
- }
+ return self.render_maybe_body(
+ ¶meterized_block.else_contents,
+ breadcrumbs,
+ blocks,
+ );
}
}
DustTag::DTHelperNotEquals(parameterized_block) => {
- let param_map: HashMap<&str, &RValue<'a>> = parameterized_block
- .params
- .iter()
- .map(|pair: &KVPair<'a>| (pair.key, &pair.value))
- .collect();
+ let param_map: HashMap<&str, &RValue<'a>> =
+ Self::get_rval_map(¶meterized_block.params);
// Special case: when comparing two RVPaths, if the
// path is equal then dust assumes the values are
// equal (otherwise, non-scalar values are
@@ -299,64 +265,39 @@ impl<'a> DustRenderer<'a> {
};
}
- let left_side: Result<&dyn ContextElement, WalkError> = match param_map.get("key") {
- None => return Ok("".to_owned()),
- Some(rval) => match rval {
- RValue::RVString(text) => Ok(text),
- RValue::RVPath(path) => walk_path(breadcrumbs, &path.keys),
- RValue::RVPositiveInteger(num) => Ok(num),
- },
- };
- let right_side: Result<&dyn ContextElement, WalkError> =
- match param_map.get("value") {
- None => Err(WalkError::CantWalk),
- Some(rval) => match rval {
- RValue::RVString(text) => Ok(text),
- RValue::RVPath(path) => walk_path(breadcrumbs, &path.keys),
- RValue::RVPositiveInteger(num) => Ok(num),
- },
+ let left_side: Result<&dyn ContextElement, WalkError> =
+ match Self::get_rval(breadcrumbs, ¶m_map, "key") {
+ None => return Ok("".to_owned()),
+ Some(res) => res,
};
+ let right_side: Result<&dyn ContextElement, WalkError> =
+ Self::get_rval(breadcrumbs, ¶m_map, "value")
+ .unwrap_or(Err(WalkError::CantWalk));
if left_side != right_side {
- match ¶meterized_block.contents {
- None => return Ok("".to_owned()),
- Some(body) => {
- let rendered_content = self.render_body(body, breadcrumbs, blocks)?;
- return Ok(rendered_content);
- }
- }
+ return self.render_maybe_body(
+ ¶meterized_block.contents,
+ breadcrumbs,
+ blocks,
+ );
} else {
- match ¶meterized_block.else_contents {
- None => return Ok("".to_owned()),
- Some(body) => {
- let rendered_content = self.render_body(body, breadcrumbs, blocks)?;
- return Ok(rendered_content);
- }
- }
+ return self.render_maybe_body(
+ ¶meterized_block.else_contents,
+ breadcrumbs,
+ blocks,
+ );
}
}
DustTag::DTHelperGreaterThan(parameterized_block) => {
- let param_map: HashMap<&str, &RValue<'a>> = parameterized_block
- .params
- .iter()
- .map(|pair: &KVPair<'a>| (pair.key, &pair.value))
- .collect();
- let left_side: Result<&dyn ContextElement, WalkError> = match param_map.get("key") {
- None => return Ok("".to_owned()),
- Some(rval) => match rval {
- RValue::RVString(text) => Ok(text),
- RValue::RVPath(path) => walk_path(breadcrumbs, &path.keys),
- RValue::RVPositiveInteger(num) => Ok(num),
- },
- };
- let right_side: Result<&dyn ContextElement, WalkError> =
- match param_map.get("value") {
- None => Err(WalkError::CantWalk),
- Some(rval) => match rval {
- RValue::RVString(text) => Ok(text),
- RValue::RVPath(path) => walk_path(breadcrumbs, &path.keys),
- RValue::RVPositiveInteger(num) => Ok(num),
- },
+ let param_map: HashMap<&str, &RValue<'a>> =
+ Self::get_rval_map(¶meterized_block.params);
+ let left_side: Result<&dyn ContextElement, WalkError> =
+ match Self::get_rval(breadcrumbs, ¶m_map, "key") {
+ None => return Ok("".to_owned()),
+ Some(res) => res,
};
+ let right_side: Result<&dyn ContextElement, WalkError> =
+ Self::get_rval(breadcrumbs, ¶m_map, "value")
+ .unwrap_or(Err(WalkError::CantWalk));
match (left_side, right_side) {
(Err(_), _) | (_, Err(_)) => match ¶meterized_block.else_contents {
None => return Ok("".to_owned()),
@@ -367,23 +308,17 @@ impl<'a> DustRenderer<'a> {
},
(Ok(left_side_unwrapped), Ok(right_side_unwrapped)) => {
if left_side_unwrapped > right_side_unwrapped {
- match ¶meterized_block.contents {
- None => return Ok("".to_owned()),
- Some(body) => {
- let rendered_content =
- self.render_body(body, breadcrumbs, blocks)?;
- return Ok(rendered_content);
- }
- }
+ return self.render_maybe_body(
+ ¶meterized_block.contents,
+ breadcrumbs,
+ blocks,
+ );
} else {
- match ¶meterized_block.else_contents {
- None => return Ok("".to_owned()),
- Some(body) => {
- let rendered_content =
- self.render_body(body, breadcrumbs, blocks)?;
- return Ok(rendered_content);
- }
- }
+ return self.render_maybe_body(
+ ¶meterized_block.else_contents,
+ breadcrumbs,
+ blocks,
+ );
}
}
}
@@ -398,7 +333,6 @@ impl<'a> DustRenderer<'a> {
/// If the value is falsey, and therefore should render the else
/// block, this will return an empty vector.
fn get_loop_elements<'b>(
- &'a self,
walk_result: Result<&'b dyn ContextElement, WalkError>,
) -> Vec<&'b dyn ContextElement> {
match walk_result {
@@ -419,6 +353,28 @@ impl<'a> DustRenderer<'a> {
},
}
}
+
+ fn get_rval_map<'b>(params: &'b Vec>) -> HashMap<&'b str, &'b RValue<'b>> {
+ params
+ .iter()
+ .map(|pair: &KVPair<'b>| (pair.key, &pair.value))
+ .collect()
+ }
+
+ fn get_rval<'b>(
+ breadcrumbs: &Vec<&'b dyn ContextElement>,
+ param_map: &HashMap<&str, &'b RValue<'b>>,
+ key: &str,
+ ) -> Option> {
+ match param_map.get(key) {
+ None => None,
+ Some(rval) => match rval {
+ RValue::RVString(text) => Some(Ok(text)),
+ RValue::RVPath(path) => Some(walk_path(breadcrumbs, &path.keys)),
+ RValue::RVPositiveInteger(num) => Some(Ok(num)),
+ },
+ }
+ }
}
#[cfg(test)]