First attempt at a section render function.
Running into an issue with generics vs dynamic references.
This commit is contained in:
parent
e5c4ba8c82
commit
f0a69d12b9
@ -1,5 +1,5 @@
|
|||||||
{#things}
|
{#things}
|
||||||
Thing: {.}
|
Thing: {.}
|
||||||
{:else}
|
{:else}
|
||||||
No things
|
No things {.}
|
||||||
{/things}
|
{/things}
|
||||||
|
@ -90,9 +90,9 @@ pub struct Span<'a> {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Container<'a> {
|
pub struct Container<'a> {
|
||||||
path: Path<'a>,
|
pub path: Path<'a>,
|
||||||
contents: Option<Body<'a>>,
|
pub contents: Option<Body<'a>>,
|
||||||
else_contents: Option<Body<'a>>,
|
pub else_contents: Option<Body<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
@ -22,7 +22,5 @@ pub trait Loopable {
|
|||||||
/// once with the context being the element at that path. Finally,
|
/// once with the context being the element at that path. Finally,
|
||||||
/// if its an array-like value then it will render n-times, once
|
/// if its an array-like value then it will render n-times, once
|
||||||
/// for each element of the array.
|
/// for each element of the array.
|
||||||
///
|
|
||||||
/// TODO: Should this return an iterator instead of a vec?
|
|
||||||
fn get_loop_elements(&self) -> Result<Vec<&dyn ContextElement>, RenderError>;
|
fn get_loop_elements(&self) -> Result<Vec<&dyn ContextElement>, RenderError>;
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,42 @@ impl<'a> DustRenderer<'a> {
|
|||||||
return val?.render(&reference.filters);
|
return val?.render(&reference.filters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DustTag::DTSection(container) => {
|
||||||
|
let val = walk_path(context, &container.path.keys);
|
||||||
|
if let Err(RenderError::WontWalk { .. }) = 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() {
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
// TODO: do filters apply? I don't think so
|
||||||
|
// but I should test
|
||||||
|
return match &container.else_contents {
|
||||||
|
Some(body) => self.render_body(&body, context),
|
||||||
|
None => Ok("".to_owned()),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
match container.contents {
|
||||||
|
None => Ok("".to_owned()),
|
||||||
|
Some(body) => {
|
||||||
|
let rendered_results: Result<Vec<String>, RenderError> =
|
||||||
|
loop_elements
|
||||||
|
.into_iter()
|
||||||
|
.map(|array_elem| self.render_body(&body, array_elem))
|
||||||
|
.collect();
|
||||||
|
let rendered_slice: &[String] = &rendered_results?;
|
||||||
|
return Ok(rendered_slice.join(""));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return Ok("".to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => (), // TODO: Implement the rest
|
_ => (), // TODO: Implement the rest
|
||||||
}
|
}
|
||||||
Ok("".to_owned())
|
Ok("".to_owned())
|
||||||
|
Loading…
Reference in New Issue
Block a user