Skip to main content

manabrew_server/
error.rs

1use std::fmt;
2
3#[derive(Debug)]
4pub enum ServerError {
5    AuthFailed(String),
6    AuthTimeout,
7    RoomNotFound(String),
8    RoomFull(String),
9    IncorrectPassword,
10    NotInRoom,
11    NotHost,
12    PlayersNotReady,
13    DeckNotSelected,
14    AlreadyInRoom(String),
15    GameAlreadyStarted,
16    GameNotInProgress,
17    FormatNotChosen,
18    InvalidDraftConfig(String),
19    InvalidResumeToken,
20    DuplicateUsername(String),
21    PlayerNotFound(String),
22    PlayerInGame(String),
23    InvalidChatMessage(String),
24    ChatRateLimited,
25    AccountRequired,
26    WebSocket(Box<tokio_tungstenite::tungstenite::Error>),
27    Serde(serde_json::Error),
28}
29
30impl fmt::Display for ServerError {
31    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32        match self {
33            Self::AuthFailed(msg) => write!(f, "Authentication failed: {msg}"),
34            Self::AuthTimeout => write!(f, "Authentication timed out"),
35            Self::RoomNotFound(id) => write!(f, "Room not found: {id}"),
36            Self::RoomFull(id) => write!(f, "Room is full: {id}"),
37            Self::IncorrectPassword => write!(f, "Incorrect room password"),
38            Self::NotInRoom => write!(f, "You are not in a room"),
39            Self::NotHost => write!(f, "Only the host can do that"),
40            Self::PlayersNotReady => write!(f, "Not all players are ready"),
41            Self::DeckNotSelected => write!(f, "You must select a deck before getting ready"),
42            Self::GameAlreadyStarted => write!(f, "Game has already started"),
43            Self::GameNotInProgress => write!(f, "No game is in progress"),
44            Self::FormatNotChosen => write!(f, "A format must be chosen before starting"),
45            Self::InvalidDraftConfig(msg) => write!(f, "Invalid draft config: {msg}"),
46            Self::InvalidResumeToken => write!(f, "Invalid resume token"),
47            Self::AlreadyInRoom(id) => write!(f, "Already in room: {id}"),
48            Self::DuplicateUsername(name) => write!(f, "Username already taken: {name}"),
49            Self::PlayerNotFound(name) => write!(f, "Player not found: {name}"),
50            Self::PlayerInGame(name) => write!(f, "Player is in a game: {name}"),
51            Self::InvalidChatMessage(msg) => write!(f, "Invalid chat message: {msg}"),
52            Self::ChatRateLimited => write!(f, "You are sending messages too quickly"),
53            Self::AccountRequired => write!(f, "Sign in to chat in General"),
54            Self::WebSocket(e) => write!(f, "WebSocket error: {e}"),
55            Self::Serde(e) => write!(f, "Serialization error: {e}"),
56        }
57    }
58}
59
60impl std::error::Error for ServerError {}
61
62impl ServerError {
63    pub fn code(&self) -> &'static str {
64        match self {
65            Self::AuthFailed(_) => "auth_failed",
66            Self::AuthTimeout => "auth_timeout",
67            Self::RoomNotFound(_) => "room_not_found",
68            Self::RoomFull(_) => "room_full",
69            Self::IncorrectPassword => "incorrect_password",
70            Self::NotInRoom => "not_in_room",
71            Self::NotHost => "not_host",
72            Self::PlayersNotReady => "players_not_ready",
73            Self::DeckNotSelected => "deck_not_selected",
74            Self::GameAlreadyStarted => "game_already_started",
75            Self::GameNotInProgress => "game_not_in_progress",
76            Self::FormatNotChosen => "format_not_chosen",
77            Self::InvalidDraftConfig(_) => "invalid_draft_config",
78            Self::InvalidResumeToken => "invalid_resume_token",
79            Self::AlreadyInRoom(_) => "already_in_room",
80            Self::DuplicateUsername(_) => "duplicate_username",
81            Self::PlayerNotFound(_) => "player_not_found",
82            Self::PlayerInGame(_) => "player_in_game",
83            Self::InvalidChatMessage(_) => "invalid_chat_message",
84            Self::ChatRateLimited => "chat_rate_limited",
85            Self::AccountRequired => "account_required",
86            Self::WebSocket(_) => "websocket_error",
87            Self::Serde(_) => "parse_error",
88        }
89    }
90}
91
92impl From<tokio_tungstenite::tungstenite::Error> for ServerError {
93    fn from(e: tokio_tungstenite::tungstenite::Error) -> Self {
94        Self::WebSocket(Box::new(e))
95    }
96}
97
98impl From<serde_json::Error> for ServerError {
99    fn from(e: serde_json::Error) -> Self {
100        Self::Serde(e)
101    }
102}