summaryrefslogtreecommitdiff
path: root/crates/messenger_common/src
diff options
context:
space:
mode:
authorSophie Forrest <git@sophieforrest.com>2024-08-30 23:13:20 +1200
committerSophie Forrest <git@sophieforrest.com>2024-08-30 23:13:44 +1200
commite3cb82a3b33bd2a2e49c58ce18d1258fb505869e (patch)
tree2375279182fb4f90f5c28560a08cda90591f608b /crates/messenger_common/src
chore: initial commit (codeberg upload)HEADmain
Diffstat (limited to '')
-rw-r--r--crates/messenger_common/src/client.rs15
-rw-r--r--crates/messenger_common/src/lib.rs77
-rw-r--r--crates/messenger_common/src/server.rs107
3 files changed, 199 insertions, 0 deletions
diff --git a/crates/messenger_common/src/client.rs b/crates/messenger_common/src/client.rs
new file mode 100644
index 0000000..69a7fd6
--- /dev/null
+++ b/crates/messenger_common/src/client.rs
@@ -0,0 +1,15 @@
+//! Messages sent from the client to the server by the messenger.
+
+use serde::{Deserialize, Serialize};
+
+/// 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 when a user joins the chat. Contains the username they wish to pick
+ SetUsername(String),
+
+ /// Sent when a user sends a message in the chat. Contains their message as
+ /// a string
+ UserMessage(String),
+}
diff --git a/crates/messenger_common/src/lib.rs b/crates/messenger_common/src/lib.rs
new file mode 100644
index 0000000..c05e870
--- /dev/null
+++ b/crates/messenger_common/src/lib.rs
@@ -0,0 +1,77 @@
+#![feature(custom_inner_attributes)]
+#![feature(lint_reasons)]
+#![feature(never_type)]
+#![feature(lazy_cell)]
+#![clippy::msrv = "1.69.0"]
+#![deny(clippy::nursery)]
+#![deny(clippy::pedantic)]
+#![deny(clippy::alloc_instead_of_core)]
+#![deny(clippy::as_underscore)]
+#![deny(clippy::clone_on_ref_ptr)]
+#![deny(clippy::create_dir)]
+#![warn(clippy::dbg_macro)]
+#![deny(clippy::default_numeric_fallback)]
+#![deny(clippy::default_union_representation)]
+#![deny(clippy::deref_by_slicing)]
+#![deny(clippy::else_if_without_else)]
+#![deny(clippy::empty_structs_with_brackets)]
+#![deny(clippy::exit)]
+#![deny(clippy::filetype_is_file)]
+#![deny(clippy::fn_to_numeric_cast)]
+#![deny(clippy::format_push_string)]
+#![deny(clippy::get_unwrap)]
+#![deny(clippy::if_then_some_else_none)]
+#![allow(
+ clippy::implicit_return,
+ reason = "returns should be done implicitly, not explicitly"
+)]
+#![deny(clippy::indexing_slicing)]
+#![deny(clippy::large_include_file)]
+#![deny(clippy::let_underscore_must_use)]
+#![deny(clippy::lossy_float_literal)]
+#![deny(clippy::map_err_ignore)]
+#![deny(clippy::mem_forget)]
+#![deny(clippy::missing_docs_in_private_items)]
+#![deny(clippy::missing_trait_methods)]
+#![deny(clippy::multiple_inherent_impl)]
+#![deny(clippy::needless_return)]
+#![deny(clippy::non_ascii_literal)]
+#![deny(clippy::panic_in_result_fn)]
+#![deny(clippy::pattern_type_mismatch)]
+#![deny(clippy::rc_buffer)]
+#![deny(clippy::rc_mutex)]
+#![deny(clippy::rest_pat_in_fully_bound_structs)]
+#![deny(clippy::same_name_method)]
+#![deny(clippy::separated_literal_suffix)]
+#![deny(clippy::str_to_string)]
+#![deny(clippy::string_add)]
+#![deny(clippy::string_slice)]
+#![deny(clippy::string_to_string)]
+#![allow(
+ clippy::tabs_in_doc_comments,
+ reason = "tabs are preferred for this project"
+)]
+#![deny(clippy::try_err)]
+#![deny(clippy::undocumented_unsafe_blocks)]
+#![deny(clippy::unnecessary_self_imports)]
+#![deny(clippy::unneeded_field_pattern)]
+#![deny(clippy::unwrap_in_result)]
+#![deny(clippy::unwrap_used)]
+#![warn(clippy::use_debug)]
+#![deny(clippy::verbose_file_reads)]
+#![deny(clippy::wildcard_dependencies)]
+#![deny(clippy::wildcard_enum_match_arm)]
+#![deny(clippy::missing_panics_doc)]
+#![deny(missing_copy_implementations)]
+#![deny(missing_debug_implementations)]
+#![deny(missing_docs)]
+#![deny(single_use_lifetimes)]
+#![deny(unsafe_code)]
+#![deny(unused)]
+
+//! # Messenger Common
+//!
+//! Exports common resources used by the messenger client and server.
+
+pub mod client;
+pub mod server;
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)
+ }
+}