graph_core/
error.rs

1use crate::NodeId;
2
3/// Errors that can arise from graph operations.
4///
5/// Methods that mutate or query a graph return `Result<T, GraphError>`
6/// whenever the operation could meaningfully fail (e.g. referencing a
7/// node that does not exist).
8///
9/// # Examples
10///
11/// ```
12/// use graph_core::{GraphError, NodeId};
13///
14/// let err = GraphError::NodeNotFound(NodeId::new(99));
15/// assert!(matches!(err, GraphError::NodeNotFound(_)));
16/// ```
17#[derive(Debug, Clone, PartialEq)]
18pub enum GraphError {
19    /// The referenced node does not exist in the graph.
20    NodeNotFound(NodeId),
21    /// An edge between these two nodes already exists.
22    EdgeAlreadyExists(NodeId, NodeId),
23    /// The operation would create a self-loop, which is disallowed.
24    SelfLoop(NodeId),
25    /// A negative-weight cycle was detected (Bellman-Ford / Floyd-Warshall).
26    NegativeCycle,
27    /// The graph is not connected where connectivity is required (e.g. MST).
28    NotConnected,
29    /// A catch-all for operations that are invalid in the current context.
30    InvalidOperation(&'static str),
31}
32
33// ── Display / Error ───────────────────────────────────────────────────────────
34
35impl std::fmt::Display for GraphError {
36    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37        match self {
38            GraphError::NodeNotFound(id) => write!(f, "node not found: {id}"),
39            GraphError::EdgeAlreadyExists(u, v) => {
40                write!(f, "edge already exists: {u} -> {v}")
41            }
42            GraphError::SelfLoop(id) => write!(f, "self-loop not allowed: {id}"),
43            GraphError::NegativeCycle => write!(f, "negative-weight cycle detected"),
44            GraphError::NotConnected => write!(f, "graph is not connected"),
45            GraphError::InvalidOperation(msg) => write!(f, "invalid operation: {msg}"),
46        }
47    }
48}
49
50impl std::error::Error for GraphError {}