1use crate::types::Span;
4use std::path::PathBuf;
5
6#[derive(thiserror::Error, Debug)]
10pub enum ForgeError {
11 #[error("Database error: {0}")]
13 DatabaseError(String),
14
15 #[error("Symbol not found: {0}")]
17 SymbolNotFound(String),
18
19 #[error("Invalid query: {0}")]
21 InvalidQuery(String),
22
23 #[error("Edit conflict in {file:?} at {span:?}")]
25 EditConflict {
26 file: PathBuf,
28 span: Span,
30 },
31
32 #[error("Verification failed: {0}")]
34 VerificationFailed(String),
35
36 #[error("Policy violation: {0}")]
38 PolicyViolation(String),
39
40 #[error("Backend not available: {0}")]
42 BackendNotAvailable(String),
43
44 #[error("CFG not available for symbol: {0:?}")]
46 CfgNotAvailable(crate::types::SymbolId),
47
48 #[error("Path overflow for symbol: {0:?}")]
50 PathOverflow(crate::types::SymbolId),
51
52 #[error("I/O error: {0}")]
54 Io(#[from] std::io::Error),
55
56 #[error("JSON error: {0}")]
58 Json(#[from] serde_json::Error),
59
60 #[error("Graph error: {0}")]
62 Graph(#[from] anyhow::Error),
63
64 #[error("Tool error: {0}")]
66 ToolError(String),
67
68 #[error("Path not allowed: {0}")]
70 PathNotAllowed(PathBuf),
71
72 #[error("File already exists: {0}")]
74 FileAlreadyExists(PathBuf),
75}
76
77pub type Result<T> = std::result::Result<T, ForgeError>;
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 fn test_error_display() {
86 let err = ForgeError::SymbolNotFound("test".to_string());
87 assert_eq!(err.to_string(), "Symbol not found: test");
88 }
89
90 #[test]
91 fn test_span_is_empty() {
92 let span = Span { start: 10, end: 10 };
93 assert!(span.is_empty());
94 }
95
96 #[test]
97 fn test_span_contains() {
98 let span = Span { start: 10, end: 20 };
99 assert!(span.contains(15));
100 assert!(!span.contains(20));
101 assert!(!span.contains(5));
102 }
103}