steid

@jamesgill /

3.0 KBCode·Blame·Raw
1use crate::domain::{DomainError, repository::RepositoryError};
2
3use super::port::{
4 GitArchiveError, GitProtocolError, GitQueryError, GitStorageError, PasswordError,
5};
6
7/// What a use case can fail with.
8///
9/// Keeps the failure sources distinct: a broken rule, broken storage, a broken hash,
10/// and a filesystem that would not cooperate are different problems with different
11/// responses, and flattening them makes a storage outage indistinguishable from a
12/// validation error.
13#[derive(Debug)]
14pub enum Error {
15 /// A domain rule was violated.
16 Domain(DomainError),
17 /// Persistence failed.
18 Repository(RepositoryError),
19 /// Hashing or verification failed for a reason other than a wrong password.
20 Password(PasswordError),
21 /// A bare repository could not be created or removed on disk.
22 GitStorage(GitStorageError),
23 /// The git protocol could not be served.
24 GitProtocol(GitProtocolError),
25 /// A repository's contents could not be read.
26 GitQuery(GitQueryError),
27 /// A repository could not be packed into an archive.
28 GitArchive(GitArchiveError),
29}
30
31impl From<DomainError> for Error {
32 fn from(error: DomainError) -> Self {
33 Self::Domain(error)
34 }
35}
36
37impl From<RepositoryError> for Error {
38 fn from(error: RepositoryError) -> Self {
39 Self::Repository(error)
40 }
41}
42
43impl From<PasswordError> for Error {
44 fn from(error: PasswordError) -> Self {
45 Self::Password(error)
46 }
47}
48
49impl From<GitStorageError> for Error {
50 fn from(error: GitStorageError) -> Self {
51 Self::GitStorage(error)
52 }
53}
54
55impl From<GitProtocolError> for Error {
56 fn from(error: GitProtocolError) -> Self {
57 Self::GitProtocol(error)
58 }
59}
60
61impl From<GitQueryError> for Error {
62 fn from(error: GitQueryError) -> Self {
63 Self::GitQuery(error)
64 }
65}
66
67impl From<GitArchiveError> for Error {
68 fn from(error: GitArchiveError) -> Self {
69 Self::GitArchive(error)
70 }
71}
72
73impl std::fmt::Display for Error {
74 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75 match self {
76 Self::Domain(error) => write!(f, "{error}"),
77 Self::Repository(error) => write!(f, "{error}"),
78 Self::Password(error) => write!(f, "{error}"),
79 Self::GitStorage(error) => write!(f, "{error}"),
80 Self::GitProtocol(error) => write!(f, "{error}"),
81 Self::GitQuery(error) => write!(f, "{error}"),
82 Self::GitArchive(error) => write!(f, "{error}"),
83 }
84 }
85}
86
87impl std::error::Error for Error {
88 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
89 match self {
90 Self::Domain(error) => Some(error),
91 Self::Repository(error) => Some(error),
92 Self::Password(error) => Some(error),
93 Self::GitStorage(error) => Some(error),
94 Self::GitProtocol(error) => Some(error),
95 Self::GitQuery(error) => Some(error),
96 Self::GitArchive(error) => Some(error),
97 }
98 }
99}
100
101pub type Result<T> = std::result::Result<T, Error>;