| 348 | type Node = N; |
| 349 | |
| 350 | fn f_down(&mut self, node: &'n Self::Node) -> Result<TreeNodeRecursion> { |
| 351 | self.id_array.push((0, None)); |
| 352 | self.visit_stack |
| 353 | .push(VisitRecord::EnterMark(self.down_index)); |
| 354 | self.down_index += 1; |
| 355 | |
| 356 | // If a node can short-circuit then some of its children might not be executed so |
| 357 | // count the occurrence either normal or conditional. |
| 358 | Ok(if self.conditional { |
| 359 | // If we are already in a conditionally evaluated subtree then continue |
| 360 | // traversal. |
| 361 | TreeNodeRecursion::Continue |
| 362 | } else { |
| 363 | // If we are already in a node that can short-circuit then start new |
| 364 | // traversals on its normal conditional children. |
| 365 | match C::conditional_children(node) { |
| 366 | Some((normal, conditional)) => { |
| 367 | normal |
| 368 | .into_iter() |
| 369 | .try_for_each(|n| n.visit(self).map(|_| ()))?; |
| 370 | self.conditional = true; |
| 371 | conditional |
| 372 | .into_iter() |
| 373 | .try_for_each(|n| n.visit(self).map(|_| ()))?; |
| 374 | self.conditional = false; |
| 375 | |
| 376 | TreeNodeRecursion::Jump |
| 377 | } |
| 378 | |
| 379 | // In case of non-short-circuit node continue the traversal. |
| 380 | _ => TreeNodeRecursion::Continue, |
| 381 | } |
| 382 | }) |
| 383 | } |
| 384 | |
| 385 | fn f_up(&mut self, node: &'n Self::Node) -> Result<TreeNodeRecursion> { |
| 386 | let (down_index, sub_node_id, sub_node_is_valid) = |