Skip to main content

clankerdiff_core/
error.rs

1//! Errors returned by the renderer-independent diff model.
2
3/// Errors produced while constructing or decoding a repository-relative path.
4#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
5pub enum RepoPathError {
6    #[error("repository path is empty")]
7    Empty,
8    /// The path contained a NUL byte.
9    #[error("repository path contains a NUL byte")]
10    Nul,
11    /// The path was absolute or contained a platform prefix.
12    #[error("repository path must be relative")]
13    Absolute,
14    /// The path attempted to escape its repository root.
15    #[error("repository path contains '.' or '..' component")]
16    Traversal,
17}
18
19impl From<std::convert::Infallible> for RepoPathError {
20    fn from(value: std::convert::Infallible) -> Self {
21        match value {}
22    }
23}
24
25#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
26#[error("unknown diff scope `{0}`; expected unstaged, staged, or both")]
27pub struct ParseDiffScopeError(pub String);
28
29/// Errors shared by model and parser adapters.
30#[derive(Debug, thiserror::Error)]
31pub enum DiffError {
32    /// A repository path could not be represented safely.
33    #[error("unsupported path encoding: {0}")]
34    UnsupportedPathEncoding(#[source] std::str::Utf8Error),
35    /// A path failed the relative-path contract.
36    #[error("invalid repository path: {0}")]
37    InvalidPath(#[from] RepoPathError),
38    /// A diff could not be parsed.
39    #[error("failed to parse diff: {source}")]
40    Parse {
41        /// Structured parser error, including the failing input span.
42        #[source]
43        source: diffy::patch_set::PatchSetParseError,
44    },
45    /// An underlying UTF-8 conversion failed.
46    #[error("invalid UTF-8: {0}")]
47    Utf8(#[from] std::str::Utf8Error),
48    /// A NUL-delimited porcelain record did not follow Git's v1 grammar.
49    #[error("invalid git porcelain v1 record")]
50    InvalidPorcelainEntry,
51}
52
53impl From<std::string::FromUtf8Error> for DiffError {
54    fn from(error: std::string::FromUtf8Error) -> Self {
55        Self::UnsupportedPathEncoding(error.utf8_error())
56    }
57}