Merge branch 'pseudo_context' into explicit_context_priority
This commit is contained in:
commit
9bdc398a6d
@ -21,6 +21,16 @@ pub trait Truthiness {
|
|||||||
|
|
||||||
pub trait Walkable {
|
pub trait Walkable {
|
||||||
fn walk(&self, segment: &str) -> Result<&dyn ContextElement, WalkError>;
|
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 {
|
pub trait Renderable {
|
||||||
|
@ -68,6 +68,10 @@ impl Walkable for IterationContext {
|
|||||||
_ => Err(WalkError::CantWalk),
|
_ => Err(WalkError::CantWalk),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_pseudo_element(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompareContextElement for IterationContext {
|
impl CompareContextElement for IterationContext {
|
||||||
|
@ -103,6 +103,10 @@ impl Walkable for ParametersContext {
|
|||||||
OwnedRValue::RVLiteral(literal) => Ok(literal),
|
OwnedRValue::RVLiteral(literal) => Ok(literal),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_pseudo_element(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for ParametersContext {
|
impl Clone for ParametersContext {
|
||||||
|
@ -17,6 +17,7 @@ use crate::renderer::inline_partial_tree::InlinePartialTreeElement;
|
|||||||
use crate::renderer::iteration_context::IterationContext;
|
use crate::renderer::iteration_context::IterationContext;
|
||||||
use crate::renderer::parameters_context::ParametersContext;
|
use crate::renderer::parameters_context::ParametersContext;
|
||||||
use crate::renderer::walking::walk_path;
|
use crate::renderer::walking::walk_path;
|
||||||
|
use std::borrow::Borrow;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -813,6 +814,15 @@ impl<'a> DustRenderer<'a> {
|
|||||||
Some(new_stack)
|
Some(new_stack)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_index_of_first_non_pseudo_element<'b, B>(breadcrumbs: &'b Vec<B>) -> Option<usize>
|
||||||
|
where
|
||||||
|
B: Borrow<dyn ContextElement + 'a>,
|
||||||
|
{
|
||||||
|
breadcrumbs
|
||||||
|
.iter()
|
||||||
|
.rposition(|b| !(*b).borrow().is_pseudo_element())
|
||||||
|
}
|
||||||
|
|
||||||
fn new_breadcrumbs_partial<'b>(
|
fn new_breadcrumbs_partial<'b>(
|
||||||
breadcrumbs: &'b Vec<&'b dyn ContextElement>,
|
breadcrumbs: &'b Vec<&'b dyn ContextElement>,
|
||||||
explicit_context_breadcrumbs: &'b Vec<&'b dyn ContextElement>,
|
explicit_context_breadcrumbs: &'b Vec<&'b dyn ContextElement>,
|
||||||
@ -837,7 +847,10 @@ impl<'a> DustRenderer<'a> {
|
|||||||
// added after the current context but before the explicit
|
// added after the current context but before the explicit
|
||||||
// context.
|
// context.
|
||||||
match explicit_context {
|
match explicit_context {
|
||||||
None => new_stack.insert(std::cmp::max(new_stack.len() - 1, 0), ctx),
|
None => new_stack.insert(
|
||||||
|
Self::get_index_of_first_non_pseudo_element(&new_stack).unwrap_or(0),
|
||||||
|
ctx,
|
||||||
|
),
|
||||||
_ => new_stack.push(ctx),
|
_ => new_stack.push(ctx),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::renderer::context_element::ContextElement;
|
use crate::renderer::context_element::ContextElement;
|
||||||
|
use crate::renderer::context_element::Walkable;
|
||||||
use crate::renderer::WalkError;
|
use crate::renderer::WalkError;
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
|
|
||||||
@ -34,6 +35,17 @@ where
|
|||||||
WalkResult::FullyWalked(output)
|
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>(
|
pub fn walk_path<'a, B, P>(
|
||||||
breadcrumbs: &'a Vec<B>,
|
breadcrumbs: &'a Vec<B>,
|
||||||
path: &Vec<P>,
|
path: &Vec<P>,
|
||||||
@ -60,17 +72,18 @@ where
|
|||||||
.borrow()
|
.borrow()
|
||||||
== "."
|
== "."
|
||||||
{
|
{
|
||||||
return match walk_path_from_single_level(
|
let first_non_pseudo_element = get_first_non_pseudo_element(breadcrumbs);
|
||||||
breadcrumbs
|
return match first_non_pseudo_element {
|
||||||
.last()
|
None => Err(WalkError::CantWalk),
|
||||||
.expect("Breadcrumbs should never be empty"),
|
Some(current_context) => {
|
||||||
&path[1..],
|
match walk_path_from_single_level(current_context, &path[1..]) {
|
||||||
) {
|
|
||||||
// If no walking was done at all or we partially walked
|
// If no walking was done at all or we partially walked
|
||||||
// then stop trying to find anything because '.' restricts
|
// then stop trying to find anything because '.' restricts
|
||||||
// us to the current scope
|
// us to the current scope
|
||||||
WalkResult::NoWalk | WalkResult::PartialWalk => Err(WalkError::CantWalk),
|
WalkResult::NoWalk | WalkResult::PartialWalk => Err(WalkError::CantWalk),
|
||||||
WalkResult::FullyWalked(new_context) => Ok(new_context),
|
WalkResult::FullyWalked(new_context) => Ok(new_context),
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
for context in breadcrumbs.iter().rev() {
|
for context in breadcrumbs.iter().rev() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user