use std::path::PathBuf; use std::fmt; #[derive(Debug)] pub enum Error { NotGitRepository, NoChanges, GitRepositoryError(git2::Error), FileReadError(PathBuf, std::io::Error), ConfigParseError(PathBuf, String), InvalidConfigFormat(PathBuf, &'static str), NoCommitTypeDetected, Cancelled, Io(std::io::Error), Json(serde_json::Error), Yaml(serde_yaml::Error), Toml(toml::de::Error), Regex(regex::Error), UnknownScope(String), Other(String), } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Error::NotGitRepository => write!(f, "Not a git repository (not found in current directory or parents)"), Error::NoChanges => write!(f, "No changes to commit"), Error::GitRepositoryError(e) => write!(f, "Failed to open git repository: {}", e), Error::FileReadError(path, e) => write!(f, "Failed to read file {}: {}", path.display(), e), Error::ConfigParseError(path, msg) => write!(f, "Failed to parse config file {}: {}", path.display(), msg), Error::InvalidConfigFormat(path, expected) => write!(f, "Invalid config format in {}: expected {}", path.display(), expected), Error::NoCommitTypeDetected => write!(f, "No commit type detected for changes"), Error::Cancelled => write!(f, "User cancelled the operation"), Error::Io(e) => write!(f, "IO error: {}", e), Error::Json(e) => write!(f, "JSON error: {}", e), Error::Yaml(e) => write!(f, "YAML error: {}", e), Error::Toml(e) => write!(f, "TOML error: {}", e), Error::Regex(e) => write!(f, "Regex error: {}", e), Error::UnknownScope(s) => write!(f, "Unknown scope detected: {}", s), Error::Other(s) => write!(f, "{}", s), } } } impl std::error::Error for Error {} impl From for Error { fn from(e: git2::Error) -> Self { Error::GitRepositoryError(e) } } impl From for Error { fn from(e: std::io::Error) -> Self { Error::Io(e) } } impl From for Error { fn from(e: serde_json::Error) -> Self { Error::Json(e) } } impl From for Error { fn from(e: serde_yaml::Error) -> Self { Error::Yaml(e) } } impl From for Error { fn from(e: toml::de::Error) -> Self { Error::Toml(e) } } impl From for Error { fn from(e: regex::Error) -> Self { Error::Regex(e) } } pub type Result = std::result::Result; impl Error { pub fn exit_code(&self) -> i32 { match self { Error::NoChanges => 1, Error::NotGitRepository => 128, _ => 1, } } }