Skipping over pseudo contexts has fixed most of the tests.

master
Tom Alexander 4 years ago
parent f04e84dc31
commit 3c9a369908
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE

@ -21,6 +21,16 @@ pub trait Truthiness {
pub trait Walkable {
fn walk(&self, segment: &str) -> Result<&dyn ContextElement, WalkError>;
/// If an element contains meta information and should not be
/// returned as the final result of a walk, this function should
/// return true.
///
/// For example, the iteration context contains $idx and $len but
/// it should not be the result of a dot-reference like `{.}`.
fn is_pseudo_element(&self) -> bool {
false
}
}
pub trait Renderable {

@ -68,6 +68,10 @@ impl Walkable for IterationContext {
_ => Err(WalkError::CantWalk),
}
}
fn is_pseudo_element(&self) -> bool {
true
}
}
impl CompareContextElement for IterationContext {

@ -103,6 +103,10 @@ impl Walkable for ParametersContext {
OwnedRValue::RVLiteral(literal) => Ok(literal),
}
}
fn is_pseudo_element(&self) -> bool {
true
}
}
impl Clone for ParametersContext {

@ -1,4 +1,5 @@
use crate::renderer::context_element::ContextElement;
use crate::renderer::context_element::Walkable;
use crate::renderer::WalkError;
use std::borrow::Borrow;
@ -34,6 +35,17 @@ where
WalkResult::FullyWalked(output)
}
pub fn get_first_non_pseudo_element<'a, B>(breadcrumbs: &'a Vec<B>) -> Option<&B>
where
B: Borrow<dyn ContextElement + 'a>,
{
breadcrumbs
.iter()
.rev()
.filter(|b| !(*b).borrow().is_pseudo_element())
.next()
}
pub fn walk_path<'a, B, P>(
breadcrumbs: &'a Vec<B>,
path: &Vec<P>,
@ -60,17 +72,22 @@ where
.borrow()
== "."
{
return match walk_path_from_single_level(
breadcrumbs
.last()
.expect("Breadcrumbs should never be empty"),
&path[1..],
) {
// If no walking was done at all or we partially walked
// then stop trying to find anything because '.' restricts
// us to the current scope
WalkResult::NoWalk | WalkResult::PartialWalk => Err(WalkError::CantWalk),
WalkResult::FullyWalked(new_context) => Ok(new_context),
let first_non_pseudo_element = get_first_non_pseudo_element(breadcrumbs);
// println!(
// "First non-pseudo element: {:?}",
// first_non_pseudo_element.map(|b| b.borrow())
// );
return match first_non_pseudo_element {
None => Err(WalkError::CantWalk),
Some(current_context) => {
match walk_path_from_single_level(current_context, &path[1..]) {
// If no walking was done at all or we partially walked
// then stop trying to find anything because '.' restricts
// us to the current scope
WalkResult::NoWalk | WalkResult::PartialWalk => Err(WalkError::CantWalk),
WalkResult::FullyWalked(new_context) => Ok(new_context),
}
}
};
}
for context in breadcrumbs.iter().rev() {

Loading…
Cancel
Save