Skip to main content

weavatrix_graph/
error.rs

1use std::fmt::{Display, Formatter};
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4#[non_exhaustive]
5pub enum GraphError {
6    EmptyNodeId,
7    InvalidKind {
8        category: &'static str,
9        value: String,
10    },
11    ConflictingNode {
12        id: String,
13    },
14    MissingEdgeSource {
15        id: String,
16    },
17    MissingEdgeTarget {
18        id: String,
19    },
20    EmptyExtractor,
21    InvalidSpan {
22        file: String,
23        reason: &'static str,
24    },
25    IndexCapacityExceeded {
26        category: &'static str,
27        count: usize,
28    },
29    InvalidTopologyEndpoint {
30        edge: usize,
31        node: usize,
32        node_count: usize,
33    },
34    ArithmeticOverflow {
35        operation: &'static str,
36    },
37    InvalidNodeIndex {
38        node: usize,
39        node_count: usize,
40    },
41    InvalidProbability {
42        numerator: u64,
43        denominator: u64,
44    },
45    InvalidAlgorithmParameter {
46        algorithm: &'static str,
47        parameter: &'static str,
48        value: String,
49    },
50    NegativeCycle {
51        algorithm: &'static str,
52    },
53}
54
55impl Display for GraphError {
56    fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
57        match self {
58            Self::EmptyNodeId => formatter.write_str("node id must not be empty"),
59            Self::InvalidKind { category, value } => {
60                write!(formatter, "invalid {category} kind: {value:?}")
61            }
62            Self::ConflictingNode { id } => {
63                write!(formatter, "node id {id} has conflicting definitions")
64            }
65            Self::MissingEdgeSource { id } => {
66                write!(formatter, "edge source does not exist: {id}")
67            }
68            Self::MissingEdgeTarget { id } => {
69                write!(formatter, "edge target does not exist: {id}")
70            }
71            Self::EmptyExtractor => formatter.write_str("provenance extractor must not be empty"),
72            Self::InvalidSpan { file, reason } => {
73                write!(formatter, "invalid source span for {file:?}: {reason}")
74            }
75            Self::IndexCapacityExceeded { category, count } => {
76                write!(
77                    formatter,
78                    "{category} count {count} exceeds u32 index capacity"
79                )
80            }
81            Self::InvalidTopologyEndpoint {
82                edge,
83                node,
84                node_count,
85            } => write!(
86                formatter,
87                "edge {edge} references node index {node}, but node count is {node_count}"
88            ),
89            Self::ArithmeticOverflow { operation } => {
90                write!(formatter, "arithmetic overflow while computing {operation}")
91            }
92            Self::InvalidNodeIndex { node, node_count } => {
93                write!(
94                    formatter,
95                    "node index {node} is outside matrix node count {node_count}"
96                )
97            }
98            Self::InvalidProbability {
99                numerator,
100                denominator,
101            } => write!(
102                formatter,
103                "probability {numerator}/{denominator} must have a nonzero denominator and be at most one"
104            ),
105            Self::InvalidAlgorithmParameter {
106                algorithm,
107                parameter,
108                value,
109            } => write!(formatter, "invalid {parameter} for {algorithm}: {value}"),
110            Self::NegativeCycle { algorithm } => {
111                write!(formatter, "{algorithm} found a reachable negative cycle")
112            }
113        }
114    }
115}
116
117impl std::error::Error for GraphError {}
118
119pub type Result<T> = std::result::Result<T, GraphError>;