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 {}