|
|
|
@ -8,31 +8,6 @@ enum WalkResult<'a> {
|
|
|
|
|
FullyWalked(&'a dyn ContextElement),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn walk_path_from_single_level<'a>(
|
|
|
|
|
context: &'a dyn ContextElement,
|
|
|
|
|
path: &[&str],
|
|
|
|
|
) -> WalkResult<'a> {
|
|
|
|
|
if path.is_empty() {
|
|
|
|
|
return WalkResult::FullyWalked(context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mut walk_failure = WalkResult::NoWalk;
|
|
|
|
|
let mut output = context;
|
|
|
|
|
for elem in path.iter() {
|
|
|
|
|
match output.walk(elem) {
|
|
|
|
|
Err(WalkError::CantWalk { .. }) => {
|
|
|
|
|
return walk_failure;
|
|
|
|
|
}
|
|
|
|
|
Ok(new_val) => {
|
|
|
|
|
walk_failure = WalkResult::PartialWalk;
|
|
|
|
|
output = new_val;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WalkResult::FullyWalked(output)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn walk_path_from_single_level_borrow<'a, P, C>(context: &'a C, path: &[P]) -> WalkResult<'a>
|
|
|
|
|
where
|
|
|
|
|
P: Borrow<str>,
|
|
|
|
@ -106,84 +81,3 @@ where
|
|
|
|
|
}
|
|
|
|
|
Err(WalkError::CantWalk)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn walk_path<'a>(
|
|
|
|
|
breadcrumbs: &Vec<&'a dyn ContextElement>,
|
|
|
|
|
path: &'a Vec<&str>,
|
|
|
|
|
) -> Result<&'a dyn ContextElement, WalkError> {
|
|
|
|
|
if path.is_empty() {
|
|
|
|
|
return Ok(*breadcrumbs
|
|
|
|
|
.last()
|
|
|
|
|
.expect("Breadcrumbs should never be empty"));
|
|
|
|
|
}
|
|
|
|
|
if *path.first().expect("Already proved path is not empty") == "." {
|
|
|
|
|
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),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
for context in breadcrumbs.iter().rev() {
|
|
|
|
|
match walk_path_from_single_level(*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 owned_walk_path<'a>(
|
|
|
|
|
breadcrumbs: &'a Vec<Box<dyn ContextElement>>,
|
|
|
|
|
path: &Vec<String>,
|
|
|
|
|
) -> Result<&'a dyn ContextElement, WalkError> {
|
|
|
|
|
if path.is_empty() {
|
|
|
|
|
return Ok(breadcrumbs
|
|
|
|
|
.last()
|
|
|
|
|
.expect("Breadcrumbs should never be empty")
|
|
|
|
|
.as_ref());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let path_reference: Vec<&str> = path.iter().map(|p| &p[..]).collect();
|
|
|
|
|
if path.first().expect("Already proved path is not empty") == "." {
|
|
|
|
|
return match walk_path_from_single_level(
|
|
|
|
|
breadcrumbs
|
|
|
|
|
.last()
|
|
|
|
|
.expect("Breadcrumbs should never be empty")
|
|
|
|
|
.as_ref(),
|
|
|
|
|
&path_reference[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(context.as_ref(), &path_reference) {
|
|
|
|
|
// 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)
|
|
|
|
|
}
|
|
|
|
|