1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
//! 图操作错误类型定义
//!
//! 提供详细的错误类型,支持错误链和上下文信息
use core::fmt;
use core::fmt::{Display, Formatter};
/// 图操作结果类型别名
pub type GraphResult<T> = Result<T, GraphError>;
/// 图操作错误类型
#[derive(Debug, Clone, PartialEq)]
pub enum GraphError {
/// 节点不存在:索引无效或超出范围
NodeNotFound {
/// 导致错误的节点索引
index: usize,
},
/// 节点已删除:generation 不匹配
NodeDeleted {
/// 导致错误的节点索引
index: usize,
/// 提供的 generation
provided: u32,
/// 当前的 generation
current: u32,
},
/// 边不存在:索引无效或超出范围
EdgeNotFound {
/// 导致错误的边索引
index: usize,
},
/// 边已删除:generation 不匹配
EdgeDeleted {
/// 导致错误的边索引
index: usize,
/// 提供的 generation
provided: u32,
/// 当前的 generation
current: u32,
},
/// 边已存在:简单图不允许重边
EdgeAlreadyExists {
/// 源节点索引
from: usize,
/// 目标节点索引
to: usize,
},
/// 不允许自环
SelfLoopNotAllowed {
/// 节点索引
node: usize,
},
/// 超过最大节点容量
GraphCapacityExceeded {
/// 当前数量
current: usize,
/// 最大容量
max: usize,
},
/// 内存分配失败
MemoryAllocationFailed {
/// 请求的大小(字节)
requested: usize,
},
/// 无效的图方向操作
InvalidDirection,
/// 图不是有向图
GraphNotDirected,
/// 图不是无向图
GraphNotUndirected,
/// 图中存在环(用于 DAG 操作)
GraphHasCycle,
/// 算法不收敛
AlgorithmNotConverged {
/// 执行的迭代次数
iterations: usize,
/// 最终误差
error: f64,
},
/// 负权环检测到(Bellman-Ford)
NegativeCycle,
/// 负权重边检测到(Dijkstra 不支持)
NegativeWeight {
/// 源节点索引
from: usize,
/// 目标节点索引
to: usize,
/// 权重值
weight: f64,
},
/// 索引越界
IndexOutOfBounds {
/// 提供的索引
index: usize,
/// 边界
bound: usize,
},
/// 未找到资源
NotFound(String),
/// 无效格式
InvalidFormat(String),
/// IO 错误
IoError(String),
}
impl Display for GraphError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
GraphError::NodeNotFound { index } => {
write!(f, "节点不存在:索引 {} 无效或超出范围", index)
}
GraphError::NodeDeleted {
index,
provided,
current,
} => {
write!(
f,
"节点已删除:索引 {} 的 generation 不匹配 (provided: {}, current: {})",
index, provided, current
)
}
GraphError::EdgeNotFound { index } => {
write!(f, "边不存在:索引 {} 无效或超出范围", index)
}
GraphError::EdgeDeleted {
index,
provided,
current,
} => {
write!(
f,
"边已删除:索引 {} 的 generation 不匹配 (provided: {}, current: {})",
index, provided, current
)
}
GraphError::EdgeAlreadyExists { from, to } => {
write!(f, "边已存在:从节点 {} 到节点 {} 的边已存在", from, to)
}
GraphError::SelfLoopNotAllowed { node } => {
write!(f, "不允许自环:节点 {} 不能作为自身的边端点", node)
}
GraphError::GraphCapacityExceeded { current, max } => {
write!(f, "超过最大容量:当前 {},最大 {}", current, max)
}
GraphError::MemoryAllocationFailed { requested } => {
write!(f, "内存分配失败:请求 {} 字节", requested)
}
GraphError::InvalidDirection => {
write!(f, "无效的图方向操作")
}
GraphError::GraphNotDirected => {
write!(f, "图不是有向图")
}
GraphError::GraphNotUndirected => {
write!(f, "图不是无向图")
}
GraphError::GraphHasCycle => {
write!(f, "图中存在环")
}
GraphError::AlgorithmNotConverged { iterations, error } => {
write!(
f,
"算法不收敛:执行 {} 次迭代后误差为 {}",
iterations, error
)
}
GraphError::NegativeCycle => {
write!(f, "检测到负权环")
}
GraphError::NegativeWeight { from, to, weight } => {
write!(
f,
"检测到负权重边:节点 {} 到 {} 的权重为 {}(Dijkstra 不支持负权重,建议使用 Bellman-Ford 算法)",
from, to, weight
)
}
GraphError::IndexOutOfBounds { index, bound } => {
write!(f, "索引越界:索引 {} 超出边界 {}", index, bound)
}
GraphError::NotFound(resource) => {
write!(f, "未找到资源:{}", resource)
}
GraphError::InvalidFormat(msg) => {
write!(f, "无效格式:{}", msg)
}
GraphError::IoError(err) => {
write!(f, "IO 错误:{}", err)
}
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for GraphError {}
impl From<GraphError> for String {
fn from(err: GraphError) -> Self {
err.to_string()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display() {
let err = GraphError::NodeNotFound { index: 42 };
assert!(err.to_string().contains("42"));
let err = GraphError::EdgeAlreadyExists { from: 1, to: 2 };
assert!(err.to_string().contains("1"));
assert!(err.to_string().contains("2"));
}
}