git_whennes/
error.rs

1use std::fmt::Debug;
2
3pub enum Error {
4    NoMergeCommit {
5        r#for: String,
6    },
7    PicoArgsError(pico_args::Error),
8    FindCommitError {
9        sha: String,
10        source: git2::Error,
11    },
12    GraphDescendantOfError {
13        commit: String,
14        ancestory: String,
15        source: git2::Error,
16    },
17    RevParseError {
18        sha: String,
19        source: git2::Error,
20    },
21    ExpectedCommitError {
22        sha: String,
23    },
24    FindRemoteError {
25        remote: String,
26        source: git2::Error,
27    },
28    Git2Error(git2::Error),
29    InvalidUtf8,
30}
31
32impl std::fmt::Display for Error {
33    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34        match self {
35            Error::NoMergeCommit { r#for } => {
36                write!(f, "No merge commit for {} found", r#for)
37            }
38            Error::PicoArgsError(e) => write!(f, "{}", e),
39            Error::FindCommitError { sha, source: _ } => {
40                write!(f, "Failed to find commit {}", sha)
41            }
42            Error::GraphDescendantOfError {
43                commit,
44                ancestory,
45                source: _,
46            } => {
47                write!(
48                    f,
49                    "Failed to determine of {} is a descendant of {}",
50                    commit, ancestory,
51                )
52            }
53            Error::RevParseError { sha, source: _ } => {
54                write!(f, "Failed to parse revision {}", sha)
55            }
56            Error::ExpectedCommitError { sha } => {
57                write!(f, "Expected {} to be a commit", sha)
58            }
59            Error::FindRemoteError { remote, source: _ } => {
60                write!(f, "Failed to find remote {}", remote)
61            }
62            Error::Git2Error(e) => write!(f, "{}", e),
63            Error::InvalidUtf8 => write!(f, "invalid UTF-8"),
64        }
65    }
66}
67
68impl Debug for Error {
69    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70        writeln!(f, "{}", self)?;
71        writeln!(f)?;
72
73        let mut maybe_e = std::error::Error::source(self);
74        while let Some(e) = maybe_e {
75            writeln!(f, "{}", e)?;
76            maybe_e = std::error::Error::source(e);
77        }
78        Ok(())
79    }
80}
81
82impl std::error::Error for Error {
83    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
84        match self {
85            Error::NoMergeCommit { r#for: _ } => None,
86            Error::PicoArgsError(e) => Some(e),
87            Error::FindCommitError { sha: _, source } => Some(source),
88            Error::GraphDescendantOfError {
89                commit: _,
90                ancestory: _,
91                source,
92            } => Some(source),
93            Error::RevParseError { sha: _, source } => Some(source),
94            Error::ExpectedCommitError { sha: _ } => None,
95            Error::FindRemoteError { remote: _, source } => Some(source),
96            Error::Git2Error(e) => e.source(),
97            Error::InvalidUtf8 => None,
98        }
99    }
100}
101
102impl From<pico_args::Error> for Error {
103    fn from(e: pico_args::Error) -> Self {
104        Self::PicoArgsError(e)
105    }
106}
107
108impl From<git2::Error> for Error {
109    fn from(e: git2::Error) -> Self {
110        Self::Git2Error(e)
111    }
112}
113
114pub type Result<T> = std::result::Result<T, Error>;