use crate::types::Span;
use std::path::PathBuf;
#[derive(thiserror::Error, Debug)]
pub enum ForgeError {
#[error("Database error: {0}")]
DatabaseError(String),
#[error("Symbol not found: {0}")]
SymbolNotFound(String),
#[error("Invalid query: {0}")]
InvalidQuery(String),
#[error("Edit conflict in {file:?} at {span:?}")]
EditConflict {
file: PathBuf,
span: Span,
},
#[error("Verification failed: {0}")]
VerificationFailed(String),
#[error("Policy violation: {0}")]
PolicyViolation(String),
#[error("Backend not available: {0}")]
BackendNotAvailable(String),
#[error("CFG not available for symbol: {0:?}")]
CfgNotAvailable(crate::types::SymbolId),
#[error("Path overflow for symbol: {0:?}")]
PathOverflow(crate::types::SymbolId),
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
#[error("Graph error: {0}")]
Graph(#[from] anyhow::Error),
#[error("Tool error: {0}")]
ToolError(String),
#[error("Path not allowed: {0}")]
PathNotAllowed(PathBuf),
#[error("File already exists: {0}")]
FileAlreadyExists(PathBuf),
}
pub type Result<T> = std::result::Result<T, ForgeError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display() {
let err = ForgeError::SymbolNotFound("test".to_string());
assert_eq!(err.to_string(), "Symbol not found: test");
}
#[test]
fn test_span_is_empty() {
let span = Span { start: 10, end: 10 };
assert!(span.is_empty());
}
#[test]
fn test_span_contains() {
let span = Span { start: 10, end: 20 };
assert!(span.contains(15));
assert!(!span.contains(20));
assert!(!span.contains(5));
}
}