grapes 0.3.0

Persistent graph data structures: Tree, Graph, Arena & more
Documentation
//! Iterators over edges

use crate::arena::ArenaItems;
use crate::graph::{Edge, EdgeId, EdgeRef, Graph};

/// Iterator over edges from a node
///
/// Order is unspecified
#[must_use]
#[derive(Debug)]
pub struct EdgesFrom<'a, NodeData: Clone, EdgeData: Clone> {
    graph: &'a Graph<NodeData, EdgeData>,
    /// Next edge ID to return. Must be valid.
    next_index: Option<EdgeId>,
}

impl<'a, NodeData, EdgeData> EdgesFrom<'a, NodeData, EdgeData>
where
    NodeData: Clone,
    EdgeData: Clone,
{
    pub(crate) fn new(graph: &'a Graph<NodeData, EdgeData>, next_index: Option<EdgeId>) -> Self {
        Self { graph, next_index }
    }
}

impl<'a, NodeData, EdgeData> Iterator for EdgesFrom<'a, NodeData, EdgeData>
where
    NodeData: Clone,
    EdgeData: Clone,
{
    type Item = EdgeRef<'a, NodeData, EdgeData>;

    fn next(&mut self) -> Option<Self::Item> {
        let current_index = self.next_index?;
        let current_edge = &self
            .graph
            .edges
            .get(current_index.0)
            .expect("invariant violation: next points to invalid edge");
        self.next_index = current_edge.next_with_from;

        Some(EdgeRef::new(self.graph, current_index))
    }
}

/// Iterator over edges to a node
///
/// Order is unspecified
#[must_use]
#[derive(Debug)]
pub struct EdgesTo<'a, NodeData: Clone, EdgeData: Clone> {
    graph: &'a Graph<NodeData, EdgeData>,
    /// Next edge ID to return. Must be valid.
    next_index: Option<EdgeId>,
}

impl<'a, NodeData, EdgeData> EdgesTo<'a, NodeData, EdgeData>
where
    NodeData: Clone,
    EdgeData: Clone,
{
    pub(crate) fn new(graph: &'a Graph<NodeData, EdgeData>, next_index: Option<EdgeId>) -> Self {
        Self { graph, next_index }
    }
}

impl<'a, NodeData, EdgeData> Iterator for EdgesTo<'a, NodeData, EdgeData>
where
    NodeData: Clone,
    EdgeData: Clone,
{
    type Item = EdgeRef<'a, NodeData, EdgeData>;

    fn next(&mut self) -> Option<Self::Item> {
        let current_index = self.next_index?;
        let current_edge = &self
            .graph
            .edges
            .get(current_index.0)
            .expect("invariant violation: next points to invalid edge");
        self.next_index = current_edge.next_with_to;

        Some(EdgeRef::new(self.graph, current_index))
    }
}

/// Iterator over all edges in a Graph
///
/// Order is unspecified
#[must_use]
pub struct GraphEdges<'a, NodeData: Clone, EdgeData: Clone> {
    graph: &'a Graph<NodeData, EdgeData>,
    inner: ArenaItems<'a, Edge<EdgeData>>,
}

impl<'a, NodeData: Clone, EdgeData: Clone> GraphEdges<'a, NodeData, EdgeData> {
    pub(crate) fn new(graph: &'a Graph<NodeData, EdgeData>) -> Self {
        Self {
            graph,
            inner: graph.edges.iter_items(),
        }
    }
}

impl<'a, NodeData: Clone, EdgeData: Clone> Iterator for GraphEdges<'a, NodeData, EdgeData> {
    type Item = EdgeRef<'a, NodeData, EdgeData>;

    fn next(&mut self) -> Option<Self::Item> {
        let (id, _edge) = self.inner.next()?;
        Some(EdgeRef::new(self.graph, EdgeId(id)))
    }
}

#[cfg(test)]
mod tests {
    use crate::graph::SimpleGraph;
    use std::collections::HashSet;
    use velcro::hash_set;

    #[test]
    fn iter_edges() {
        let mut graph = SimpleGraph::new();

        let a = graph.insert_node(1).id();
        let b = graph.insert_node(2).id();
        graph.insert_edge(a, a, 10).unwrap();
        graph.insert_edge(a, b, 20).unwrap();

        assert_eq!(
            graph
                .iter_edges()
                .map(|edge| *edge.data())
                .collect::<HashSet<_>>(),
            hash_set!(10, 20)
        )
    }

    #[test]
    fn iter_edges_from() {
        let mut graph = SimpleGraph::new();

        let a = graph.insert_node(1).id();
        let b = graph.insert_node(2).id();
        graph.insert_edge(a, a, 10).unwrap();
        graph.insert_edge(a, b, 20).unwrap();
        graph.insert_edge(b, a, 30).unwrap();
        graph.insert_edge(b, b, 40).unwrap();

        assert_eq!(
            graph
                .get_node(a)
                .unwrap()
                .iter_edges_from()
                .map(|edge| *edge.data())
                .collect::<HashSet<_>>(),
            hash_set!(10, 20)
        )
    }

    #[test]
    fn iter_edges_to() {
        let mut graph = SimpleGraph::new();

        let a = graph.insert_node(1).id();
        let b = graph.insert_node(2).id();
        graph.insert_edge(a, a, 10).unwrap();
        graph.insert_edge(a, b, 20).unwrap();
        graph.insert_edge(b, a, 30).unwrap();
        graph.insert_edge(b, b, 40).unwrap();

        assert_eq!(
            graph
                .get_node(a)
                .unwrap()
                .iter_edges_to()
                .map(|edge| *edge.data())
                .collect::<HashSet<_>>(),
            hash_set!(10, 30)
        )
    }
}