Render the else block in sections if the path does not exist or if the path can't be walked.
This fixes all existing compliance tests.
This commit is contained in:
parent
cc6dbefcdb
commit
e957caf386
1
js/test_cases/render_unusual_types/input5.json
Normal file
1
js/test_cases/render_unusual_types/input5.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
[true, false, null]
|
11
src/bin.rs
11
src/bin.rs
@ -65,11 +65,7 @@ fn read_context_from_stdin() -> serde_json::Value {
|
|||||||
.read_to_string(&mut buffer)
|
.read_to_string(&mut buffer)
|
||||||
.expect("Failed to read stdin");
|
.expect("Failed to read stdin");
|
||||||
|
|
||||||
let parsed: serde_json::Value = serde_json::from_str(&buffer).expect("Failed to parse json");
|
serde_json::from_str(&buffer).expect("Failed to parse json")
|
||||||
match parsed {
|
|
||||||
serde_json::Value::Object(obj) => serde_json::value::Value::Object(obj),
|
|
||||||
_ => panic!("Expected context to be an object"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContextElement for serde_json::Value {}
|
impl ContextElement for serde_json::Value {}
|
||||||
@ -112,7 +108,10 @@ impl Walkable for serde_json::Value {
|
|||||||
segment: segment.to_string(),
|
segment: segment.to_string(),
|
||||||
elem: self,
|
elem: self,
|
||||||
}),
|
}),
|
||||||
serde_json::Value::Array(_arr) => todo!("Arrays not supported yet"),
|
serde_json::Value::Array(_arr) => Err(RenderError::CantWalk {
|
||||||
|
segment: segment.to_string(),
|
||||||
|
elem: self,
|
||||||
|
}),
|
||||||
serde_json::Value::Object(obj) => {
|
serde_json::Value::Object(obj) => {
|
||||||
obj.get(segment)
|
obj.get(segment)
|
||||||
.map(|val| val as _)
|
.map(|val| val as _)
|
||||||
|
@ -107,17 +107,16 @@ impl<'a> DustRenderer<'a> {
|
|||||||
if let Err(RenderError::WontWalk { .. }) = val {
|
if let Err(RenderError::WontWalk { .. }) = val {
|
||||||
// If reference does not exist in the context, it becomes an empty string
|
// If reference does not exist in the context, it becomes an empty string
|
||||||
return Ok("".to_owned());
|
return Ok("".to_owned());
|
||||||
|
} else if let Err(RenderError::CantWalk { .. }) = val {
|
||||||
|
// If the context type does not support walking, it becomes an empty string
|
||||||
|
return Ok("".to_owned());
|
||||||
} else {
|
} else {
|
||||||
return val?.render(&reference.filters);
|
return val?.render(&reference.filters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DustTag::DTSection(container) => {
|
DustTag::DTSection(container) => {
|
||||||
let val = walk_path(context, &container.path.keys);
|
let val = walk_path(context, &container.path.keys);
|
||||||
if let Err(RenderError::WontWalk { .. }) = val {
|
let loop_elements: Vec<&dyn ContextElement> = self.get_loop_elements(val)?;
|
||||||
// If reference does not exist in the context, it becomes an empty string
|
|
||||||
return Ok("".to_owned());
|
|
||||||
} else {
|
|
||||||
let loop_elements: Vec<&dyn ContextElement> = val?.get_loop_elements()?;
|
|
||||||
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
|
||||||
@ -134,8 +133,7 @@ impl<'a> DustRenderer<'a> {
|
|||||||
match &container.contents {
|
match &container.contents {
|
||||||
None => return Ok("".to_owned()),
|
None => return Ok("".to_owned()),
|
||||||
Some(body) => {
|
Some(body) => {
|
||||||
let rendered_results: Result<Vec<String>, RenderError> =
|
let rendered_results: Result<Vec<String>, RenderError> = loop_elements
|
||||||
loop_elements
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|array_elem| array_elem.render_body(self, &body))
|
.map(|array_elem| array_elem.render_body(self, &body))
|
||||||
.collect();
|
.collect();
|
||||||
@ -145,7 +143,6 @@ impl<'a> DustRenderer<'a> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
DustTag::DTSpecial(special) => {
|
DustTag::DTSpecial(special) => {
|
||||||
return Ok(match special {
|
return Ok(match special {
|
||||||
Special::Space => " ",
|
Special::Space => " ",
|
||||||
@ -160,6 +157,25 @@ impl<'a> DustRenderer<'a> {
|
|||||||
}
|
}
|
||||||
Ok("".to_owned())
|
Ok("".to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the elements to loop over for a section.
|
||||||
|
///
|
||||||
|
/// 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, RenderError<'b>>,
|
||||||
|
) -> Result<Vec<&'b dyn ContextElement>, RenderError<'b>> {
|
||||||
|
if let Err(RenderError::WontWalk { .. }) = walk_result {
|
||||||
|
// If reference does not exist in the context, render the else block
|
||||||
|
Ok(vec![])
|
||||||
|
} else if let Err(RenderError::CantWalk { .. }) = walk_result {
|
||||||
|
// If the context type does not support walking, render the else block
|
||||||
|
Ok(vec![])
|
||||||
|
} else {
|
||||||
|
Ok(walk_result?.get_loop_elements()?)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn walk_path<'a>(
|
fn walk_path<'a>(
|
||||||
|
Loading…
Reference in New Issue
Block a user