From 65445cc8fcbb456e85f4adf9f7fb62516533858a Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sun, 31 May 2020 16:16:21 -0400 Subject: [PATCH] Finished implementing the new tree walking. --- src/renderer/tree_walking.rs | 65 ++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 11 deletions(-) diff --git a/src/renderer/tree_walking.rs b/src/renderer/tree_walking.rs index 65f6cbd..4cb2c41 100644 --- a/src/renderer/tree_walking.rs +++ b/src/renderer/tree_walking.rs @@ -10,22 +10,44 @@ enum WalkResult<'a> { FullyWalked(&'a dyn IntoContextElement), } -fn walk_path_from_single_level<'a, P, C>(context: &'a C, path: &[P]) -> WalkResult<'a> +fn walk_path_from_single_level<'a, P>( + context: &'a dyn IntoContextElement, + path: &[P], +) -> WalkResult<'a> where P: Borrow, - C: Borrow, { - todo!() + 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.borrow()) { + Err(WalkError::CantWalk { .. }) => { + return walk_failure; + } + Ok(new_val) => { + walk_failure = WalkResult::PartialWalk; + output = new_val; + } + } + } + + WalkResult::FullyWalked(output) } fn get_first_non_pseudo_element<'a, B>( breadcrumbs: &'a BreadcrumbTreeNode, -) -> Option<&'a dyn IntoContextElement> +) -> Option<&'a dyn BreadcrumbTree> where B: IntoContextElement, { - todo!() - // breadcrumbs.iter().filter(|b| b.is_pseudo_element()).next() + breadcrumbs + .breadcrumb_iter() + .filter(|b| b.get_ice().is_pseudo_element()) + .next() } pub fn walk_path<'a, B, P>( @@ -41,12 +63,33 @@ where (Some(breadcrumbs), None) => return Ok(breadcrumbs.get_ice()), (Some(breadcrumbs), Some(path_first)) if path_first.borrow() == "." => { let first_non_pseudo_element = get_first_non_pseudo_element(breadcrumbs); - // return match first_non_pseudo_element { - // None => Err(WalkError::CantWalk), - // Some(current_context) - // } + return match first_non_pseudo_element { + None => Err(WalkError::CantWalk), + Some(current_context) => { + match walk_path_from_single_level(current_context.get_ice(), &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), + } + } + }; + } + (Some(breadcrumbs), Some(path_first)) => { + for context in breadcrumbs.ice_iter() { + 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), + } + } } - (Some(breadcrumbs), Some(path_first)) => (), } Err(WalkError::CantWalk)