indextree icon indicating copy to clipboard operation
indextree copied to clipboard

Feature Request Walker Iterator

Open momed-sakka opened this issue 10 months ago • 1 comments
trafficstars

Hi, Would it possible to add a walker iterator that takes a function and advance based on Control value. this is very similar to petgraph dfs

pub enum WalkerState {
    Continue,
    Break,
// Stop ?
}
pub struct Walker<'a, T, F> {
    arena: &'a Arena<T>,
    root: NodeId,
    next: Option<NodeEdge>,
    val: F,
}

impl<'a, T, F> Walker<'a, T, F>
where
    F: Fn(&Node<T>) -> WalkerState,
{
    pub fn new(arena: &'a Arena<T>, current: NodeId, val: F) -> Self {
        Self {
            arena,
            root: current,
            next: Some(NodeEdge::Start(current)),
            val,
        }
    }

    #[must_use]
    pub fn next_traverse(&self, next: NodeEdge) -> Option<NodeEdge> {
        match next {
            NodeEdge::Start(node) => {
                match (self.arena[node].first_child(), (self.val)(&self.arena[node]),) {
                    (Some(first_child), WalkerState::Continue) => {
                        Some(NodeEdge::Start(first_child))
                    }
                    (_, _) => Some(NodeEdge::End(node)),
                }
            }
            NodeEdge::End(node) => {
                let node = &self.arena[node];
                match node.next_sibling() {
                    Some(next_sibling) => Some(NodeEdge::Start(next_sibling)),
                    None => node.parent().map(NodeEdge::End),
                }
            }
        }
    }

    /// Calculates the next node.
    fn next_of_next(&self, next: NodeEdge) -> Option<NodeEdge> {
        if next == NodeEdge::End(self.root) {
            return None;
        }
        self.next_traverse(next)
    }
}
impl<T, F> Iterator for Walker<'_, T, F>
where
    F: Fn(&Node<T>) -> WalkerState,
{
    type Item = NodeEdge;

    fn next(&mut self) -> Option<NodeEdge> {
        let next = self.next.take()?;
        self.next = self.next_of_next(next);
        Some(next)
    }
}

momed-sakka avatar Jan 16 '25 19:01 momed-sakka

@nchouba thank you for the feature request! It sounds valuable to me, do you consider to propose the changes as PR?

saschagrunert avatar Jan 20 '25 08:01 saschagrunert