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>;