steid

@jamesgill /

1.6 KBCode·Blame·Raw
1use crate::domain::{DomainError, repository::RepositoryError};
2
3use super::port::PasswordError;
4
5/// What a use case can fail with.
6///
7/// Keeps the three failure sources distinct: a broken rule, broken storage, and a
8/// broken hash are different problems with different responses, and flattening them
9/// makes a storage outage indistinguishable from a validation error.
10#[derive(Debug)]
11pub enum Error {
12 /// A domain rule was violated.
13 Domain(DomainError),
14 /// Persistence failed.
15 Repository(RepositoryError),
16 /// Hashing or verification failed for a reason other than a wrong password.
17 Password(PasswordError),
18}
19
20impl From<DomainError> for Error {
21 fn from(error: DomainError) -> Self {
22 Self::Domain(error)
23 }
24}
25
26impl From<RepositoryError> for Error {
27 fn from(error: RepositoryError) -> Self {
28 Self::Repository(error)
29 }
30}
31
32impl From<PasswordError> for Error {
33 fn from(error: PasswordError) -> Self {
34 Self::Password(error)
35 }
36}
37
38impl std::fmt::Display for Error {
39 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40 match self {
41 Self::Domain(error) => write!(f, "{error}"),
42 Self::Repository(error) => write!(f, "{error}"),
43 Self::Password(error) => write!(f, "{error}"),
44 }
45 }
46}
47
48impl std::error::Error for Error {
49 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
50 match self {
51 Self::Domain(error) => Some(error),
52 Self::Repository(error) => Some(error),
53 Self::Password(error) => Some(error),
54 }
55 }
56}
57
58pub type Result<T> = std::result::Result<T, Error>;