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}
46
47impl Display for GraphError {
48 fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
49 match self {
50 Self::EmptyNodeId => formatter.write_str("node id must not be empty"),
51 Self::InvalidKind { category, value } => {
52 write!(formatter, "invalid {category} kind: {value:?}")
53 }
54 Self::ConflictingNode { id } => {
55 write!(formatter, "node id {id} has conflicting definitions")
56 }
57 Self::MissingEdgeSource { id } => {
58 write!(formatter, "edge source does not exist: {id}")
59 }
60 Self::MissingEdgeTarget { id } => {
61 write!(formatter, "edge target does not exist: {id}")
62 }
63 Self::EmptyExtractor => formatter.write_str("provenance extractor must not be empty"),
64 Self::InvalidSpan { file, reason } => {
65 write!(formatter, "invalid source span for {file:?}: {reason}")
66 }
67 Self::IndexCapacityExceeded { category, count } => {
68 write!(
69 formatter,
70 "{category} count {count} exceeds u32 index capacity"
71 )
72 }
73 Self::InvalidTopologyEndpoint {
74 edge,
75 node,
76 node_count,
77 } => write!(
78 formatter,
79 "edge {edge} references node index {node}, but node count is {node_count}"
80 ),
81 Self::ArithmeticOverflow { operation } => {
82 write!(formatter, "arithmetic overflow while computing {operation}")
83 }
84 Self::InvalidNodeIndex { node, node_count } => {
85 write!(
86 formatter,
87 "node index {node} is outside matrix node count {node_count}"
88 )
89 }
90 Self::InvalidProbability {
91 numerator,
92 denominator,
93 } => write!(
94 formatter,
95 "probability {numerator}/{denominator} must have a nonzero denominator and be at most one"
96 ),
97 }
98 }
99}
100
101impl std::error::Error for GraphError {}
102
103pub type Result<T> = std::result::Result<T, GraphError>;