fish_lib/game/
errors.rs

1use crate::game::errors::database::GameDatabaseError;
2use crate::game::errors::item_event::GameItemEventError;
3use crate::game::errors::repository::GameRepositoryError;
4use crate::game::errors::resource::GameResourceError;
5use thiserror::Error;
6
7pub mod database;
8pub mod item_event;
9pub mod repository;
10pub mod resource;
11
12pub type GameResult<T> = Result<T, GameError>;
13
14#[derive(Error, Debug)]
15pub enum GameError {
16    #[error(transparent)]
17    Database(#[from] GameDatabaseError),
18    #[error(transparent)]
19    ItemEvent(#[from] GameItemEventError),
20    #[error(transparent)]
21    Repository(#[from] GameRepositoryError),
22    #[error(transparent)]
23    Resource(#[from] GameResourceError),
24    #[error("Unexpected error: {msg}")]
25    Unexpected {
26        msg: String,
27        #[source]
28        source: Box<dyn std::error::Error>,
29    },
30}
31
32impl GameError {
33    pub fn unexpected(error: Box<dyn std::error::Error>) -> Self {
34        Self::Unexpected {
35            msg: error.to_string(),
36            source: error,
37        }
38    }
39
40    pub fn as_database_error(&self) -> Option<&GameDatabaseError> {
41        match self {
42            Self::Database(e) => Some(e),
43            _ => None,
44        }
45    }
46
47    pub fn as_item_event_error(&self) -> Option<&GameItemEventError> {
48        match self {
49            Self::ItemEvent(e) => Some(e),
50            _ => None,
51        }
52    }
53
54    pub fn as_repository_error(&self) -> Option<&GameRepositoryError> {
55        match self {
56            Self::Repository(e) => Some(e),
57            _ => None,
58        }
59    }
60
61    pub fn as_resource_error(&self) -> Option<&GameResourceError> {
62        match self {
63            Self::Resource(e) => Some(e),
64            _ => None,
65        }
66    }
67
68    pub fn is_database_error(&self) -> bool {
69        matches!(self, Self::Database(_))
70    }
71
72    pub fn is_item_event_error(&self) -> bool {
73        matches!(self, Self::ItemEvent(_))
74    }
75
76    pub fn is_repository_error(&self) -> bool {
77        matches!(self, Self::Repository(_))
78    }
79
80    pub fn is_resource_error(&self) -> bool {
81        matches!(self, Self::Resource(_))
82    }
83
84    pub fn is_already_exists(&self) -> bool {
85        matches!(
86            self,
87            Self::Resource(GameResourceError::UserAlreadyExists { .. })
88                | Self::Resource(GameResourceError::LocationAlreadyUnlocked { .. })
89        )
90    }
91
92    pub fn is_not_found(&self) -> bool {
93        matches!(
94            self,
95            Self::Resource(GameResourceError::UserNotFound { .. })
96                | Self::Resource(GameResourceError::FishingHistoryNotFound { .. })
97                | Self::Resource(GameResourceError::LocationNotFound { .. })
98                | Self::Resource(GameResourceError::SpeciesNotFound { .. })
99                | Self::Resource(GameResourceError::NoFishingHistory { .. })
100                | Self::Repository(GameRepositoryError::Database(GameDatabaseError::NotFound))
101                | Self::Resource(GameResourceError::ItemNotFound { .. })
102        )
103    }
104
105    pub fn is_unmet_requirements(&self) -> bool {
106        matches!(
107            self,
108            Self::Resource(GameResourceError::UnmetLocationUnlockRequirements { .. })
109        )
110    }
111}
112
113impl From<Box<dyn std::error::Error>> for GameError {
114    fn from(error: Box<dyn std::error::Error>) -> Self {
115        match error {
116            e if e.is::<GameError>() => *e.downcast::<GameError>().unwrap(),
117            e if e.is::<GameDatabaseError>() => {
118                GameError::Database(*e.downcast::<GameDatabaseError>().unwrap())
119            }
120            e if e.is::<GameRepositoryError>() => {
121                GameError::Repository(*e.downcast::<GameRepositoryError>().unwrap())
122            }
123            e if e.is::<GameResourceError>() => {
124                GameError::Resource(*e.downcast::<GameResourceError>().unwrap())
125            }
126            e => Self::unexpected(e),
127        }
128    }
129}