use std::{
error::Error,
fmt::{Debug, Display, Formatter},
ops::{Deref, DerefMut},
};
mod for_reqwest;
#[derive(Clone)]
pub struct GameError {
kind: Box<GameErrorKind>,
}
#[derive(Clone, Debug)]
pub enum GameErrorKind {
ServiceError { external_code: i64, source: String, message: String },
}
impl From<GameErrorKind> for GameError {
fn from(value: GameErrorKind) -> Self {
GameError { kind: Box::new(value) }
}
}
impl Error for GameError {}
impl Error for GameErrorKind {}
impl Debug for GameError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Debug::fmt(&self.kind, f)
}
}
impl Display for GameError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Display::fmt(&self.kind, f)
}
}
impl Display for GameErrorKind {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
GameErrorKind::ServiceError { external_code, source, message } => {
write!(f, "ServiceError {{ external_code: {}, source: {}, message: {} }}", external_code, source, message)
}
}
}
}
impl Deref for GameError {
type Target = GameErrorKind;
fn deref(&self) -> &Self::Target {
&self.kind
}
}
impl DerefMut for GameError {
fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
&mut self.kind
}
}
impl GameError {
pub fn service_error(source: impl Into<String>, message: impl Into<String>) -> GameError {
GameError {
kind: Box::new(GameErrorKind::ServiceError { external_code: 0, source: source.into(), message: message.into() }),
}
}
pub fn set_code(&mut self, code: i64) {
match self.deref_mut() {
GameErrorKind::ServiceError { external_code, .. } => {
*external_code = code;
}
}
}
pub fn with_code(mut self, code: i64) -> Self {
self.set_code(code);
self
}
}