Initial implementation combining owned_walk_path and walk_path. Works everywhere except one spot.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use crate::renderer::context_element::ContextElement;
|
||||
use crate::renderer::WalkError;
|
||||
use std::borrow::Borrow;
|
||||
|
||||
enum WalkResult<'a> {
|
||||
NoWalk,
|
||||
@@ -32,6 +33,80 @@ fn walk_path_from_single_level<'a>(
|
||||
WalkResult::FullyWalked(output)
|
||||
}
|
||||
|
||||
fn walk_path_from_single_level_borrow<'a, P, C>(context: &'a C, path: &[P]) -> WalkResult<'a>
|
||||
where
|
||||
P: Borrow<str>,
|
||||
C: Borrow<dyn ContextElement + 'a>,
|
||||
{
|
||||
if path.is_empty() {
|
||||
return WalkResult::FullyWalked(context.borrow());
|
||||
}
|
||||
|
||||
let mut walk_failure = WalkResult::NoWalk;
|
||||
let mut output = context.borrow();
|
||||
for elem in path.iter() {
|
||||
match output.borrow().walk(elem.borrow()) {
|
||||
Err(WalkError::CantWalk { .. }) => {
|
||||
return walk_failure;
|
||||
}
|
||||
Ok(new_val) => {
|
||||
walk_failure = WalkResult::PartialWalk;
|
||||
output = new_val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WalkResult::FullyWalked(output)
|
||||
}
|
||||
|
||||
pub fn walk_path_combined<'a, B, P>(
|
||||
breadcrumbs: &'a Vec<B>,
|
||||
path: &Vec<P>,
|
||||
) -> Result<&'a dyn ContextElement, WalkError>
|
||||
where
|
||||
B: Borrow<dyn ContextElement + 'a>,
|
||||
P: Borrow<str>,
|
||||
{
|
||||
if path.is_empty() {
|
||||
return Ok(breadcrumbs
|
||||
.last()
|
||||
.expect("Breadcrumbs should never be empty.")
|
||||
.borrow());
|
||||
}
|
||||
if path
|
||||
.first()
|
||||
.expect("Already proved path is not empty")
|
||||
.borrow()
|
||||
== "."
|
||||
{
|
||||
return match walk_path_from_single_level_borrow(
|
||||
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),
|
||||
};
|
||||
}
|
||||
for context in breadcrumbs.iter().rev() {
|
||||
match walk_path_from_single_level_borrow(context, path) {
|
||||
// If no walking was done at all, keep looping
|
||||
WalkResult::NoWalk => {}
|
||||
// If we partially walked then stop trying to find
|
||||
// anything
|
||||
WalkResult::PartialWalk => {
|
||||
return Err(WalkError::CantWalk);
|
||||
}
|
||||
WalkResult::FullyWalked(new_context) => return Ok(new_context),
|
||||
}
|
||||
}
|
||||
Err(WalkError::CantWalk)
|
||||
}
|
||||
|
||||
pub fn walk_path<'a>(
|
||||
breadcrumbs: &Vec<&'a dyn ContextElement>,
|
||||
path: &'a Vec<&str>,
|
||||
|
||||
Reference in New Issue
Block a user