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)
|
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(
|
fn render_body(
|
||||||
&'a self,
|
&'a self,
|
||||||
body: &'a Body,
|
body: &'a Body,
|
||||||
@ -130,16 +142,13 @@ impl<'a> DustRenderer<'a> {
|
|||||||
}
|
}
|
||||||
DustTag::DTSection(container) => {
|
DustTag::DTSection(container) => {
|
||||||
let val = walk_path(breadcrumbs, &container.path.keys);
|
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() {
|
if loop_elements.is_empty() {
|
||||||
// Oddly enough if the value is falsey (like
|
// Oddly enough if the value is falsey (like
|
||||||
// an empty array or null), Dust uses the
|
// an empty array or null), Dust uses the
|
||||||
// original context before walking the path as
|
// original context before walking the path as
|
||||||
// the context for rendering the else block
|
// the context for rendering the else block
|
||||||
return match &container.else_contents {
|
return self.render_maybe_body(&container.else_contents, breadcrumbs, blocks);
|
||||||
Some(body) => self.render_body(&body, breadcrumbs, blocks),
|
|
||||||
None => Ok("".to_owned()),
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
match &container.contents {
|
match &container.contents {
|
||||||
None => return Ok("".to_owned()),
|
None => return Ok("".to_owned()),
|
||||||
@ -160,34 +169,22 @@ impl<'a> DustRenderer<'a> {
|
|||||||
}
|
}
|
||||||
DustTag::DTExists(container) => {
|
DustTag::DTExists(container) => {
|
||||||
let val = walk_path(breadcrumbs, &container.path.keys);
|
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() {
|
return if loop_elements.is_empty() {
|
||||||
return match &container.else_contents {
|
self.render_maybe_body(&container.else_contents, breadcrumbs, blocks)
|
||||||
Some(body) => self.render_body(&body, breadcrumbs, blocks),
|
|
||||||
None => Ok("".to_owned()),
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
return match &container.contents {
|
self.render_maybe_body(&container.contents, breadcrumbs, blocks)
|
||||||
None => Ok("".to_owned()),
|
|
||||||
Some(body) => self.render_body(&body, breadcrumbs, blocks),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
DustTag::DTNotExists(container) => {
|
DustTag::DTNotExists(container) => {
|
||||||
let val = walk_path(breadcrumbs, &container.path.keys);
|
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() {
|
return if !loop_elements.is_empty() {
|
||||||
return match &container.else_contents {
|
self.render_maybe_body(&container.else_contents, breadcrumbs, blocks)
|
||||||
Some(body) => self.render_body(&body, breadcrumbs, blocks),
|
|
||||||
None => Ok("".to_owned()),
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
return match &container.contents {
|
self.render_maybe_body(&container.contents, breadcrumbs, blocks)
|
||||||
None => Ok("".to_owned()),
|
|
||||||
Some(body) => self.render_body(&body, breadcrumbs, blocks),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
DustTag::DTPartial(partial) => {
|
DustTag::DTPartial(partial) => {
|
||||||
if partial.params.is_empty() {
|
if partial.params.is_empty() {
|
||||||
let rendered_content =
|
let rendered_content =
|
||||||
@ -202,34 +199,19 @@ impl<'a> DustRenderer<'a> {
|
|||||||
return Ok(rendered_content);
|
return Ok(rendered_content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DustTag::DTInlinePartial(named_block) => {
|
DustTag::DTInlinePartial(_named_block) => {
|
||||||
// Inline partials are blank during rendering (they get injected into blocks)
|
// Inline partials are blank during rendering (they get injected into blocks)
|
||||||
return Ok("".to_owned());
|
return Ok("".to_owned());
|
||||||
}
|
}
|
||||||
DustTag::DTBlock(named_block) => {
|
DustTag::DTBlock(named_block) => {
|
||||||
match blocks.get_block(named_block.name) {
|
return match blocks.get_block(named_block.name) {
|
||||||
None => match &named_block.contents {
|
None => self.render_maybe_body(&named_block.contents, breadcrumbs, blocks),
|
||||||
None => return Ok("".to_owned()),
|
Some(interior) => self.render_maybe_body(interior, breadcrumbs, blocks),
|
||||||
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);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
DustTag::DTHelperEquals(parameterized_block) => {
|
DustTag::DTHelperEquals(parameterized_block) => {
|
||||||
let param_map: HashMap<&str, &RValue<'a>> = parameterized_block
|
let param_map: HashMap<&str, &RValue<'a>> =
|
||||||
.params
|
Self::get_rval_map(¶meterized_block.params);
|
||||||
.iter()
|
|
||||||
.map(|pair: &KVPair<'a>| (pair.key, &pair.value))
|
|
||||||
.collect();
|
|
||||||
// Special case: when comparing two RVPaths, if the
|
// Special case: when comparing two RVPaths, if the
|
||||||
// path is equal then dust assumes the values are
|
// path is equal then dust assumes the values are
|
||||||
// equal (otherwise, non-scalar 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") {
|
let left_side: Result<&dyn ContextElement, WalkError> =
|
||||||
|
match Self::get_rval(breadcrumbs, ¶m_map, "key") {
|
||||||
None => return Ok("".to_owned()),
|
None => return Ok("".to_owned()),
|
||||||
Some(rval) => match rval {
|
Some(res) => res,
|
||||||
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> =
|
let right_side: Result<&dyn ContextElement, WalkError> =
|
||||||
match param_map.get("value") {
|
Self::get_rval(breadcrumbs, ¶m_map, "value")
|
||||||
None => Err(WalkError::CantWalk),
|
.unwrap_or(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),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
if left_side == right_side {
|
if left_side == right_side {
|
||||||
match ¶meterized_block.contents {
|
return self.render_maybe_body(
|
||||||
None => return Ok("".to_owned()),
|
¶meterized_block.contents,
|
||||||
Some(body) => {
|
breadcrumbs,
|
||||||
let rendered_content = self.render_body(body, breadcrumbs, blocks)?;
|
blocks,
|
||||||
return Ok(rendered_content);
|
);
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
match ¶meterized_block.else_contents {
|
return self.render_maybe_body(
|
||||||
None => return Ok("".to_owned()),
|
¶meterized_block.else_contents,
|
||||||
Some(body) => {
|
breadcrumbs,
|
||||||
let rendered_content = self.render_body(body, breadcrumbs, blocks)?;
|
blocks,
|
||||||
return Ok(rendered_content);
|
);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DustTag::DTHelperNotEquals(parameterized_block) => {
|
DustTag::DTHelperNotEquals(parameterized_block) => {
|
||||||
let param_map: HashMap<&str, &RValue<'a>> = parameterized_block
|
let param_map: HashMap<&str, &RValue<'a>> =
|
||||||
.params
|
Self::get_rval_map(¶meterized_block.params);
|
||||||
.iter()
|
|
||||||
.map(|pair: &KVPair<'a>| (pair.key, &pair.value))
|
|
||||||
.collect();
|
|
||||||
// Special case: when comparing two RVPaths, if the
|
// Special case: when comparing two RVPaths, if the
|
||||||
// path is equal then dust assumes the values are
|
// path is equal then dust assumes the values are
|
||||||
// equal (otherwise, non-scalar 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") {
|
let left_side: Result<&dyn ContextElement, WalkError> =
|
||||||
|
match Self::get_rval(breadcrumbs, ¶m_map, "key") {
|
||||||
None => return Ok("".to_owned()),
|
None => return Ok("".to_owned()),
|
||||||
Some(rval) => match rval {
|
Some(res) => res,
|
||||||
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> =
|
let right_side: Result<&dyn ContextElement, WalkError> =
|
||||||
match param_map.get("value") {
|
Self::get_rval(breadcrumbs, ¶m_map, "value")
|
||||||
None => Err(WalkError::CantWalk),
|
.unwrap_or(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),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
if left_side != right_side {
|
if left_side != right_side {
|
||||||
match ¶meterized_block.contents {
|
return self.render_maybe_body(
|
||||||
None => return Ok("".to_owned()),
|
¶meterized_block.contents,
|
||||||
Some(body) => {
|
breadcrumbs,
|
||||||
let rendered_content = self.render_body(body, breadcrumbs, blocks)?;
|
blocks,
|
||||||
return Ok(rendered_content);
|
);
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
match ¶meterized_block.else_contents {
|
return self.render_maybe_body(
|
||||||
None => return Ok("".to_owned()),
|
¶meterized_block.else_contents,
|
||||||
Some(body) => {
|
breadcrumbs,
|
||||||
let rendered_content = self.render_body(body, breadcrumbs, blocks)?;
|
blocks,
|
||||||
return Ok(rendered_content);
|
);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DustTag::DTHelperGreaterThan(parameterized_block) => {
|
DustTag::DTHelperGreaterThan(parameterized_block) => {
|
||||||
let param_map: HashMap<&str, &RValue<'a>> = parameterized_block
|
let param_map: HashMap<&str, &RValue<'a>> =
|
||||||
.params
|
Self::get_rval_map(¶meterized_block.params);
|
||||||
.iter()
|
let left_side: Result<&dyn ContextElement, WalkError> =
|
||||||
.map(|pair: &KVPair<'a>| (pair.key, &pair.value))
|
match Self::get_rval(breadcrumbs, ¶m_map, "key") {
|
||||||
.collect();
|
|
||||||
let left_side: Result<&dyn ContextElement, WalkError> = match param_map.get("key") {
|
|
||||||
None => return Ok("".to_owned()),
|
None => return Ok("".to_owned()),
|
||||||
Some(rval) => match rval {
|
Some(res) => res,
|
||||||
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> =
|
let right_side: Result<&dyn ContextElement, WalkError> =
|
||||||
match param_map.get("value") {
|
Self::get_rval(breadcrumbs, ¶m_map, "value")
|
||||||
None => Err(WalkError::CantWalk),
|
.unwrap_or(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),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
match (left_side, right_side) {
|
match (left_side, right_side) {
|
||||||
(Err(_), _) | (_, Err(_)) => match ¶meterized_block.else_contents {
|
(Err(_), _) | (_, Err(_)) => match ¶meterized_block.else_contents {
|
||||||
None => return Ok("".to_owned()),
|
None => return Ok("".to_owned()),
|
||||||
@ -367,23 +308,17 @@ impl<'a> DustRenderer<'a> {
|
|||||||
},
|
},
|
||||||
(Ok(left_side_unwrapped), Ok(right_side_unwrapped)) => {
|
(Ok(left_side_unwrapped), Ok(right_side_unwrapped)) => {
|
||||||
if left_side_unwrapped > right_side_unwrapped {
|
if left_side_unwrapped > right_side_unwrapped {
|
||||||
match ¶meterized_block.contents {
|
return self.render_maybe_body(
|
||||||
None => return Ok("".to_owned()),
|
¶meterized_block.contents,
|
||||||
Some(body) => {
|
breadcrumbs,
|
||||||
let rendered_content =
|
blocks,
|
||||||
self.render_body(body, breadcrumbs, blocks)?;
|
);
|
||||||
return Ok(rendered_content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
match ¶meterized_block.else_contents {
|
return self.render_maybe_body(
|
||||||
None => return Ok("".to_owned()),
|
¶meterized_block.else_contents,
|
||||||
Some(body) => {
|
breadcrumbs,
|
||||||
let rendered_content =
|
blocks,
|
||||||
self.render_body(body, breadcrumbs, blocks)?;
|
);
|
||||||
return Ok(rendered_content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -398,7 +333,6 @@ impl<'a> DustRenderer<'a> {
|
|||||||
/// If the value is falsey, and therefore should render the else
|
/// If the value is falsey, and therefore should render the else
|
||||||
/// block, this will return an empty vector.
|
/// block, this will return an empty vector.
|
||||||
fn get_loop_elements<'b>(
|
fn get_loop_elements<'b>(
|
||||||
&'a self,
|
|
||||||
walk_result: Result<&'b dyn ContextElement, WalkError>,
|
walk_result: Result<&'b dyn ContextElement, WalkError>,
|
||||||
) -> Vec<&'b dyn ContextElement> {
|
) -> Vec<&'b dyn ContextElement> {
|
||||||
match walk_result {
|
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)]
|
#[cfg(test)]
|
||||||
|
Loading…
Reference in New Issue
Block a user