Skip to main content

bidirected_adjacency_array/
compare.rs

1use thiserror::Error;
2
3use crate::{
4    graph::BidirectedAdjacencyArray,
5    index::{EdgeIndex, GraphIndexInteger, NodeIndex},
6};
7
8#[derive(Debug, Error)]
9pub enum GraphComparisonError<IndexType> {
10    #[error("the number of nodes in the graphs differ")]
11    NodeCountMismatch,
12
13    #[error("the number of edges in the graphs differ")]
14    EdgeCountMismatch,
15
16    #[error("node data mismatch at node index {0}")]
17    NodeDataMismatch(NodeIndex<IndexType>),
18
19    #[error("edge data mismatch at edge index {0}")]
20    EdgeDataMismatch(EdgeIndex<IndexType>),
21
22    #[error("edge endpoint mismatch at edge index {0}")]
23    EdgeEndpointMismatch(EdgeIndex<IndexType>),
24}
25
26impl<IndexType: GraphIndexInteger, NodeData, EdgeData>
27    BidirectedAdjacencyArray<IndexType, NodeData, EdgeData>
28{
29    /// Compares this graph to another graph.
30    ///
31    /// The comparison returns `Ok` if all nodes and edges are identical in both graphs.
32    /// Otherwise, it returns an `Err` describing the differences.
33    pub fn compare(&self, other: &Self) -> Result<(), GraphComparisonError<IndexType>>
34    where
35        NodeData: Eq,
36        EdgeData: Eq,
37    {
38        if self.node_count() != other.node_count() {
39            return Err(GraphComparisonError::NodeCountMismatch);
40        }
41
42        if self.edge_count() != other.edge_count() {
43            return Err(GraphComparisonError::EdgeCountMismatch);
44        }
45
46        for node_index in self.iter_nodes() {
47            let self_node_data = self.node_data(node_index);
48            let other_node_data = other.node_data(node_index);
49
50            if self_node_data != other_node_data {
51                return Err(GraphComparisonError::NodeDataMismatch(node_index));
52            }
53        }
54
55        for edge_index in self.iter_edges() {
56            let self_edge = self.edge(edge_index);
57            let other_edge = other.edge(edge_index);
58
59            if self_edge.data() != other_edge.data() {
60                return Err(GraphComparisonError::EdgeDataMismatch(edge_index));
61            }
62
63            if self_edge.from() != other_edge.from() || self_edge.to() != other_edge.to() {
64                return Err(GraphComparisonError::EdgeEndpointMismatch(edge_index));
65            }
66        }
67
68        Ok(())
69    }
70
71    #[cfg(test)]
72    pub fn expect_equal(&self, other: &Self)
73    where
74        NodeData: Eq,
75        EdgeData: Eq,
76    {
77        match self.compare(other) {
78            Ok(()) => { /* All good. */ }
79            Err(error @ GraphComparisonError::EdgeEndpointMismatch(edge_index)) => {
80                let expected_edge = self.edge(edge_index);
81                let actual_edge = other.edge(edge_index);
82
83                let expected_from = expected_edge.from();
84                let expected_to = expected_edge.to();
85                let actual_from = actual_edge.from();
86                let actual_to = actual_edge.to();
87
88                panic!(
89                    "{error}:\nExpected ({}, {})\nActual   ({}, {})",
90                    expected_from, expected_to, actual_from, actual_to,
91                );
92            }
93            Err(e) => panic!("Graphs differ: {:?}", e),
94        }
95    }
96}