Skip to main content

git_vet/
error.rs

1use std::fmt;
2
3use thiserror::Error;
4
5use crate::path::{PathError, RepoPath};
6use crate::remote::RemoteError;
7
8#[derive(Debug, Error)]
9pub enum AppError {
10    #[error("git operation failed while {operation}: {details}")]
11    Git {
12        operation: &'static str,
13        details: String,
14    },
15    #[error("repository has no worktree")]
16    MissingWorktree,
17    #[error("path is not valid UTF-8")]
18    NonUtf8Path,
19    #[error("path escapes the repository root")]
20    PathOutsideRepo,
21    #[error("path must be absolute")]
22    NonAbsolutePath,
23    #[error("empty paths are not valid tracked files")]
24    EmptyPath,
25    #[error("repo path is invalid: {details}")]
26    InvalidRepoPath { details: &'static str },
27    #[error("path is not tracked at HEAD: {0}")]
28    PathNotTracked(RepoPath),
29    #[error("path is a submodule/gitlink and is out of scope: {0}")]
30    PathIsSubmodule(RepoPath),
31    #[error("failed to read vetignore file: {0}")]
32    Vetignore(String),
33    #[error("missing git config user.name")]
34    MissingUserName,
35    #[error("missing git config user.email")]
36    MissingUserEmail,
37    #[error("git config {key} is not valid UTF-8: {details}")]
38    NonUtf8GitConfig { key: &'static str, details: String },
39    #[error(
40        "target paths have uncommitted working-tree changes; rerun with --allow-dirty to proceed with committed HEAD contents"
41    )]
42    DirtyPathsRequireAllowDirty,
43    #[error("aborted because target paths have uncommitted working-tree changes")]
44    DirtyPathsDeclined,
45    #[error("invalid review channel {channel:?}: {details}")]
46    InvalidChannel { channel: String, details: String },
47    #[error("sync remote error: {0}")]
48    Remote(#[from] RemoteError),
49    #[error("I/O error: {0}")]
50    Io(#[from] std::io::Error),
51    #[error("JSON error: {0}")]
52    Json(#[from] serde_json::Error),
53}
54
55impl From<PathError> for AppError {
56    fn from(error: PathError) -> Self {
57        match error {
58            PathError::NonUtf8 => Self::NonUtf8Path,
59            PathError::OutsideRepo => Self::PathOutsideRepo,
60            PathError::NonAbsolute => Self::NonAbsolutePath,
61            PathError::EmptyPath => Self::EmptyPath,
62            PathError::EmptyComponent => Self::InvalidRepoPath {
63                details: "path contains an empty component",
64            },
65            PathError::CurrentDirComponent => Self::InvalidRepoPath {
66                details: "path contains a current-directory component",
67            },
68            PathError::NulByte => Self::InvalidRepoPath {
69                details: "path contains a NUL byte",
70            },
71        }
72    }
73}
74
75pub(crate) fn git_error(operation: &'static str, source: impl fmt::Display) -> AppError {
76    AppError::Git {
77        operation,
78        details: source.to_string(),
79    }
80}