Cleaning up and factoring out reused code in the renderer.
This commit is contained in:
parent
0f90fa2c7e
commit
b53a9e1837
@ -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<Body>,
|
||||
breadcrumbs: &Vec<&'a dyn ContextElement>,
|
||||
blocks: &'a InlinePartialTreeElement<'a>,
|
||||
) -> Result<String, RenderError> {
|
||||
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<KVPair<'b>>) -> 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<Result<&'b dyn ContextElement, WalkError>> {
|
||||
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)]
|
||||
|
Loading…
Reference in New Issue
Block a user