use crate::arena::ArenaItems;
use crate::graph::{Edge, EdgeId, EdgeRef, Graph};
#[must_use]
#[derive(Debug)]
pub struct EdgesFrom<'a, NodeData: Clone, EdgeData: Clone> {
graph: &'a Graph<NodeData, EdgeData>,
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))
}
}
#[must_use]
#[derive(Debug)]
pub struct EdgesTo<'a, NodeData: Clone, EdgeData: Clone> {
graph: &'a Graph<NodeData, EdgeData>,
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))
}
}
#[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)
)
}
}