Need to do loop elements.

This commit is contained in:
Tom Alexander 2020-05-09 14:10:38 -04:00
parent fcb2f3fc4d
commit 2712126b3c
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
4 changed files with 25 additions and 39 deletions

View File

@ -58,33 +58,23 @@ impl error::Error for RenderError<'_> {
} }
} }
impl fmt::Display for WalkError<'_> { impl fmt::Display for WalkError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
WalkError::CantWalk { segment, elem } => { WalkError::CantWalk => write!(f, "Failed to walk"),
write!(f, "Tried to walk to {} from {:?}", segment, elem)
}
WalkError::NotFound { path, breadcrumbs } => {
write!(f, "Could not find {:?} in {:?}", path, breadcrumbs)
}
} }
} }
} }
impl fmt::Debug for WalkError<'_> { impl fmt::Debug for WalkError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
WalkError::CantWalk { segment, elem } => { WalkError::CantWalk => write!(f, "Failed to walk"),
write!(f, "Tried to walk to {} from {:?}", segment, elem)
}
WalkError::NotFound { path, breadcrumbs } => {
write!(f, "Could not find {:?} in {:?}", path, breadcrumbs)
}
} }
} }
} }
impl error::Error for WalkError<'_> { impl error::Error for WalkError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> { fn source(&self) -> Option<&(dyn error::Error + 'static)> {
None None
} }

View File

@ -11,6 +11,7 @@ pub use context_element::Renderable;
pub use context_element::Walkable; pub use context_element::Walkable;
pub use errors::CompileError; pub use errors::CompileError;
pub use errors::RenderError; pub use errors::RenderError;
pub use errors::WalkError;
pub use renderer::compile_template; pub use renderer::compile_template;
pub use renderer::CompiledTemplate; pub use renderer::CompiledTemplate;
pub use renderer::DustRenderer; pub use renderer::DustRenderer;

View File

@ -4,6 +4,7 @@ use crate::renderer::context_element::ContextElement;
use crate::renderer::Loopable; use crate::renderer::Loopable;
use crate::renderer::RenderError; use crate::renderer::RenderError;
use crate::renderer::Renderable; use crate::renderer::Renderable;
use crate::renderer::WalkError;
use crate::renderer::Walkable; use crate::renderer::Walkable;
use std::collections::HashMap; use std::collections::HashMap;
@ -44,11 +45,8 @@ impl<'a> Loopable for ParametersContext<'a> {
} }
impl<'a> Walkable for ParametersContext<'a> { impl<'a> Walkable for ParametersContext<'a> {
fn walk(&self, segment: &str) -> Result<&dyn ContextElement, RenderError> { fn walk(&self, segment: &str) -> Result<&dyn ContextElement, WalkError> {
// TODO: Actually implement // TODO: Actually implement
Err(RenderError::CantWalk { Err(WalkError::CantWalk)
segment: segment.to_string(),
elem: self,
})
} }
} }

View File

@ -102,7 +102,7 @@ impl<'a> DustRenderer<'a> {
DustTag::DTReference(reference) => { DustTag::DTReference(reference) => {
let val = walk_path(breadcrumbs, &reference.path.keys); let val = walk_path(breadcrumbs, &reference.path.keys);
match val { match val {
Err(RenderError::NotFound { .. }) => return Ok("".to_owned()), Err(WalkError::CantWalk) => return Ok("".to_owned()),
Ok(final_val) => { Ok(final_val) => {
let loop_elements = final_val.get_loop_elements()?; let loop_elements = final_val.get_loop_elements()?;
if loop_elements.is_empty() { if loop_elements.is_empty() {
@ -111,7 +111,6 @@ impl<'a> DustRenderer<'a> {
return final_val.render(&reference.filters); return final_val.render(&reference.filters);
} }
} }
Err(render_error) => return Err(render_error),
} }
} }
DustTag::DTSection(container) => { DustTag::DTSection(container) => {
@ -218,48 +217,46 @@ enum WalkResult<'a> {
fn walk_path_from_single_level<'a>( fn walk_path_from_single_level<'a>(
context: &'a dyn ContextElement, context: &'a dyn ContextElement,
path: &Vec<&str>, path: &Vec<&str>,
) -> Result<WalkResult<'a>, RenderError<'a>> { ) -> WalkResult<'a> {
if path.is_empty() { if path.is_empty() {
return Ok(WalkResult::FullyWalked(context)); return WalkResult::FullyWalked(context);
} }
let mut walk_failure = WalkResult::NoWalk; let mut walk_failure = WalkResult::NoWalk;
let mut output = context; let mut output = context;
for elem in path.iter() { for elem in path.iter() {
let new_val = output.walk(elem); let new_val = output.walk(elem);
if let Err(WalkError::CantWalk { .. }) = new_val { match output.walk(elem) {
return Ok(walk_failure); Err(WalkError::CantWalk { .. }) => {
return walk_failure;
} }
Ok(new_val) => {
walk_failure = WalkResult::PartialWalk; walk_failure = WalkResult::PartialWalk;
output = new_val?; output = new_val;
}
}
} }
Ok(WalkResult::FullyWalked(output)) WalkResult::FullyWalked(output)
} }
fn walk_path<'a>( fn walk_path<'a>(
breadcrumbs: &Vec<&'a dyn ContextElement>, breadcrumbs: &Vec<&'a dyn ContextElement>,
path: &'a Vec<&str>, path: &'a Vec<&str>,
) -> Result<&'a dyn ContextElement, RenderError<'a>> { ) -> Result<&'a dyn ContextElement, WalkError> {
for context in breadcrumbs.iter().rev() { for context in breadcrumbs.iter().rev() {
match walk_path_from_single_level(*context, path)? { match walk_path_from_single_level(*context, path) {
// If no walking was done at all, keep looping // If no walking was done at all, keep looping
WalkResult::NoWalk => {} WalkResult::NoWalk => {}
// If we partially walked then stop trying to find // If we partially walked then stop trying to find
// anything // anything
WalkResult::PartialWalk => { WalkResult::PartialWalk => {
return Err(RenderError::NotFound { return Err(WalkError::CantWalk);
path: path,
breadcrumbs: breadcrumbs.clone(),
});
} }
WalkResult::FullyWalked(new_context) => return Ok(new_context), WalkResult::FullyWalked(new_context) => return Ok(new_context),
} }
} }
Err(RenderError::NotFound { Err(WalkError::CantWalk)
path: path,
breadcrumbs: breadcrumbs.clone(),
})
} }
#[cfg(test)] #[cfg(test)]