diff options
Diffstat (limited to 'crates/messenger_common/src/server.rs')
| -rw-r--r-- | crates/messenger_common/src/server.rs | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/crates/messenger_common/src/server.rs b/crates/messenger_common/src/server.rs new file mode 100644 index 0000000..678d812 --- /dev/null +++ b/crates/messenger_common/src/server.rs @@ -0,0 +1,107 @@ +//! Messages sent from the server to the client by the messenger. + +use std::collections::HashSet; + +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +/// Represents the type of message being sent between the client and the server +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +#[serde(rename_all = "camelCase")] +pub enum MessageType { + /// Sent to the client to indicate an error made by the client + Error(Error), + + /// Sent to a client on the initial join, indicating the online users + OnlineUsers(HashSet<String>), + + /// Sent when a user joins the chat. Contains their username + UserJoined(String), + + /// Sent when a user disconnects from the chat. Contains their username + UserLeft(String), + + /// Sent when a user sends a message in the chat. Contains their message + UserMessage(UserMessage), +} + +/// Errors the server may respond with when performing operations +#[derive(Clone, Debug, Deserialize, Eq, Error, PartialEq, Serialize)] +#[serde(rename_all = "camelCase")] +pub enum Error { + /// Cannot process the sent message + #[error("server cannot process the received message")] + CannotProcess, + + /// Message sent was invalid + #[error("server received invalid message")] + InvalidMessage, + + /// Expected different message than received + #[error("server received unexpected message (expected {expected:?}, received {received:?}")] + UnexpectedMessage { + /// Message the server expected to receive + expected: crate::client::MessageType, + + /// Message the server received + received: crate::client::MessageType, + }, + + /// Username chosen is not available + #[error("chosen username ({chosen_username}) has already been taken")] + UsernameNotAvailable { + /// Username that was chosen, but is not available + chosen_username: String, + }, +} + +/// Represents a message sent through a websocket +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct UserMessage { + /// Content of the message + content: String, + + /// The name of the message sender + sender: String, + + /// Timestamp indicating when this message was sent + #[serde(with = "time::serde::iso8601")] + timestamp: time::OffsetDateTime, +} + +impl UserMessage { + /// Constructs a new instance of the [`UserMessage`]. + #[must_use] + pub const fn new(content: String, sender: String, timestamp: time::OffsetDateTime) -> Self { + Self { + content, + sender, + timestamp, + } + } + + /// Retrieves a reference to the content of the [`UserMessage`]. + #[must_use] + pub const fn content(&self) -> &String { + &self.content + } + + /// Retrieves a reference to the sender of the [`UserMessage`]. + #[must_use] + pub const fn sender(&self) -> &String { + &self.sender + } + + /// Retrieves a timestamp to the content of the [`UserMessage`]. + #[must_use] + pub const fn timestamp(&self) -> &time::OffsetDateTime { + &self.timestamp + } +} + +impl From<UserMessage> for MessageType { + fn from(val: UserMessage) -> Self { + Self::UserMessage(val) + } +} |