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 WebSocket(Box<tokio_tungstenite::tungstenite::Error>),
22 Serde(serde_json::Error),
23}
24
25impl fmt::Display for ServerError {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 match self {
28 Self::AuthFailed(msg) => write!(f, "Authentication failed: {}", msg),
29 Self::AuthTimeout => write!(f, "Authentication timed out"),
30 Self::RoomNotFound(id) => write!(f, "Room not found: {}", id),
31 Self::RoomFull(id) => write!(f, "Room is full: {}", id),
32 Self::IncorrectPassword => write!(f, "Incorrect room password"),
33 Self::NotInRoom => write!(f, "You are not in a room"),
34 Self::NotHost => write!(f, "Only the host can do that"),
35 Self::PlayersNotReady => write!(f, "Not all players are ready"),
36 Self::DeckNotSelected => write!(f, "You must select a deck before getting ready"),
37 Self::GameAlreadyStarted => write!(f, "Game has already started"),
38 Self::GameNotInProgress => write!(f, "No game is in progress"),
39 Self::FormatNotChosen => write!(f, "A format must be chosen before starting"),
40 Self::InvalidDraftConfig(msg) => write!(f, "Invalid draft config: {}", msg),
41 Self::InvalidResumeToken => write!(f, "Invalid resume token"),
42 Self::AlreadyInRoom(id) => write!(f, "Already in room: {}", id),
43 Self::DuplicateUsername(name) => write!(f, "Username already taken: {}", name),
44 Self::WebSocket(e) => write!(f, "WebSocket error: {}", e),
45 Self::Serde(e) => write!(f, "Serialization error: {}", e),
46 }
47 }
48}
49
50impl std::error::Error for ServerError {}
51
52impl ServerError {
53 pub fn code(&self) -> &'static str {
54 match self {
55 Self::AuthFailed(_) => "auth_failed",
56 Self::AuthTimeout => "auth_timeout",
57 Self::RoomNotFound(_) => "room_not_found",
58 Self::RoomFull(_) => "room_full",
59 Self::IncorrectPassword => "incorrect_password",
60 Self::NotInRoom => "not_in_room",
61 Self::NotHost => "not_host",
62 Self::PlayersNotReady => "players_not_ready",
63 Self::DeckNotSelected => "deck_not_selected",
64 Self::GameAlreadyStarted => "game_already_started",
65 Self::GameNotInProgress => "game_not_in_progress",
66 Self::FormatNotChosen => "format_not_chosen",
67 Self::InvalidDraftConfig(_) => "invalid_draft_config",
68 Self::InvalidResumeToken => "invalid_resume_token",
69 Self::AlreadyInRoom(_) => "already_in_room",
70 Self::DuplicateUsername(_) => "duplicate_username",
71 Self::WebSocket(_) => "websocket_error",
72 Self::Serde(_) => "parse_error",
73 }
74 }
75}
76
77impl From<tokio_tungstenite::tungstenite::Error> for ServerError {
78 fn from(e: tokio_tungstenite::tungstenite::Error) -> Self {
79 Self::WebSocket(Box::new(e))
80 }
81}
82
83impl From<serde_json::Error> for ServerError {
84 fn from(e: serde_json::Error) -> Self {
85 Self::Serde(e)
86 }
87}