added chat types from chat-service
This commit is contained in:
parent
1b8cd0a46a
commit
19c4567323
File diff suppressed because it is too large
Load Diff
|
@ -3,9 +3,10 @@ name = "chat-types"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
[lib]
|
[lib]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
chrono = { version = "0.4", features = [ "serde" ] }
|
chrono = { version = "0.4", features = [ "serde" ] }
|
||||||
|
sqlx = { version = "0.6.0", features = [ "runtime-tokio-rustls", "mysql", "chrono", "decimal", "offline" ] }
|
||||||
|
serde_json = { version = "1" }
|
|
@ -0,0 +1,160 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use sqlx::{
|
||||||
|
mysql::{MySqlTypeInfo, MySqlValueRef},
|
||||||
|
FromRow, MySql,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Used for Both registering delivered and seen time in messages.
|
||||||
|
/// The reasoning for this is that a chatroom can have many users
|
||||||
|
/// and the backend needs to be able to tell when each of them
|
||||||
|
/// has seen this message.
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub struct TimeSensitiveAction {
|
||||||
|
pub time: DateTime<Utc>,
|
||||||
|
pub by: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub struct TimeSensitiveActionVec {
|
||||||
|
pub list: Vec<TimeSensitiveAction>,
|
||||||
|
}
|
||||||
|
impl sqlx::Type<MySql> for TimeSensitiveActionVec {
|
||||||
|
fn type_info() -> MySqlTypeInfo {
|
||||||
|
<str as sqlx::Type<MySql>>::type_info()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl sqlx::Encode<'_, MySql> for TimeSensitiveActionVec {
|
||||||
|
fn encode_by_ref(&self, buf: &mut Vec<u8>) -> sqlx::encode::IsNull {
|
||||||
|
let json_str = serde_json::to_string(self).unwrap();
|
||||||
|
<&str as sqlx::Encode<MySql>>::encode(&json_str, buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl sqlx::Decode<'_, MySql> for TimeSensitiveActionVec {
|
||||||
|
fn decode(value: MySqlValueRef<'_>) -> Result<Self, sqlx::error::BoxDynError> {
|
||||||
|
match <&str as sqlx::Decode<MySql>>::decode(value).map(ToOwned::to_owned) {
|
||||||
|
Ok(json_str) => match serde_json::from_str(json_str.as_str()) {
|
||||||
|
Ok(time_sensitive_action) => Ok(time_sensitive_action),
|
||||||
|
Err(error) => Err(Box::new(error)),
|
||||||
|
},
|
||||||
|
Err(error) => Err(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TimeSensitiveAction {
|
||||||
|
pub fn new(by: u32) -> Self {
|
||||||
|
Self {
|
||||||
|
time: Utc::now(),
|
||||||
|
by,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Base message for chat rooms.
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FromRow)]
|
||||||
|
pub struct ChatMessage {
|
||||||
|
pub id: u32,
|
||||||
|
/// User id
|
||||||
|
#[serde(rename = "fromId")]
|
||||||
|
pub from_id: u32,
|
||||||
|
/// ChatRoom id (Not a user id)
|
||||||
|
#[serde(rename = "toId")]
|
||||||
|
pub to_id: u32,
|
||||||
|
pub message: ChatMessageContent,
|
||||||
|
/// This must always be there. Since its created.
|
||||||
|
#[serde(rename = "timeSent")]
|
||||||
|
pub time_sent: DateTime<Utc>,
|
||||||
|
/// This is a Vec because there can be many recipients.
|
||||||
|
#[serde(rename = "timeDelivered")]
|
||||||
|
pub time_delivered: TimeSensitiveActionVec,
|
||||||
|
/// This is a Vec because there can be many recipients.
|
||||||
|
#[serde(rename = "timeSeen")]
|
||||||
|
pub time_seen: TimeSensitiveActionVec,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub enum ChatMessageContent {
|
||||||
|
Text(String),
|
||||||
|
Image(Vec<u8>),
|
||||||
|
Video(Vec<u8>),
|
||||||
|
Audio(Vec<u8>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sqlx::Type<MySql> for ChatMessageContent {
|
||||||
|
fn type_info() -> MySqlTypeInfo {
|
||||||
|
<str as sqlx::Type<MySql>>::type_info()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl sqlx::Encode<'_, MySql> for ChatMessageContent {
|
||||||
|
fn encode_by_ref(&self, buf: &mut Vec<u8>) -> sqlx::encode::IsNull {
|
||||||
|
let json_str = serde_json::to_string(self).unwrap();
|
||||||
|
<&str as sqlx::Encode<MySql>>::encode(&json_str, buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl sqlx::Decode<'_, MySql> for ChatMessageContent {
|
||||||
|
fn decode(value: MySqlValueRef<'_>) -> Result<Self, sqlx::error::BoxDynError> {
|
||||||
|
match <&str as sqlx::Decode<MySql>>::decode(value).map(ToOwned::to_owned) {
|
||||||
|
Ok(json_str) => match serde_json::from_str(json_str.as_str()) {
|
||||||
|
Ok(time_sensitive_action) => Ok(time_sensitive_action),
|
||||||
|
Err(error) => Err(Box::new(error)),
|
||||||
|
},
|
||||||
|
Err(error) => Err(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ChatSendable {
|
||||||
|
/// Creates a new message, automatically sets the time that the message was sent to the current time in UTC.
|
||||||
|
fn new(from: u32, message: ChatMessageSender) -> Self;
|
||||||
|
/// Sets the time that the message was delivered to the current time in UTC.
|
||||||
|
fn delivered(&mut self, by: u32);
|
||||||
|
/// Sets the time that the message was seen to the current time in UTC.
|
||||||
|
fn seen(&mut self, by: u32);
|
||||||
|
/// This returns the content of a given message, the backend might need this in the future.
|
||||||
|
fn get_content(&self) -> &ChatMessageContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChatSendable for ChatMessage {
|
||||||
|
fn new(from_id: u32, message: ChatMessageSender) -> Self {
|
||||||
|
Self {
|
||||||
|
id: 0, //TODO: Assign a random number
|
||||||
|
from_id,
|
||||||
|
to_id: message.to,
|
||||||
|
message: message.message,
|
||||||
|
time_sent: Utc::now(),
|
||||||
|
time_delivered: TimeSensitiveActionVec { list: Vec::new() },
|
||||||
|
time_seen: TimeSensitiveActionVec { list: Vec::new() },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delivered(&mut self, by: u32) {
|
||||||
|
self.time_delivered.list.push(TimeSensitiveAction::new(by));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn seen(&mut self, by: u32) {
|
||||||
|
self.time_seen.list.push(TimeSensitiveAction::new(by));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_content(&self) -> &ChatMessageContent {
|
||||||
|
&self.message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This is what clients use to send messages (DTO)
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub struct ChatMessageSender {
|
||||||
|
pub message: ChatMessageContent,
|
||||||
|
pub to: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This is what should be sent across the broadcast channels
|
||||||
|
/// All of them use the same object so that the client can just replace its own
|
||||||
|
/// Copy of it with the server's authority.
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub enum BroadcastMessage {
|
||||||
|
NewMessageRequest(ChatMessageSender),
|
||||||
|
NewMessage(ChatMessage),
|
||||||
|
DeliveredUpdate(ChatMessage),
|
||||||
|
SeenUpdate(ChatMessage),
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub enum ChatMessageUpdate {
|
||||||
|
/// User id that got the message delivered to, and the time it was delivered.
|
||||||
|
Delivered(u32, DateTime<Utc>),
|
||||||
|
/// User id that saw the message, and the time it was seen.
|
||||||
|
Seen(u32, DateTime<Utc>),
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
|
||||||
|
pub struct ChatRoom {
|
||||||
|
pub id: u32,
|
||||||
|
pub title: String,
|
||||||
|
#[serde(rename = "ownerId")]
|
||||||
|
pub owner_id: u32,
|
||||||
|
#[serde(rename = "timeCreated")]
|
||||||
|
pub time_created: DateTime<Utc>,
|
||||||
|
#[serde(rename = "lastUpdated")]
|
||||||
|
pub last_updated: DateTime<Utc>,
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
pub mod chat_message;
|
||||||
|
pub mod chat_message_update;
|
||||||
|
pub mod chat_room;
|
40
src/lib.rs
40
src/lib.rs
|
@ -1,39 +1 @@
|
||||||
use chrono::{DateTime, Utc};
|
pub mod domain;
|
||||||
use serde::{Serialize, Deserialize};
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
||||||
pub struct Message {
|
|
||||||
pub id: String,
|
|
||||||
pub text: String,
|
|
||||||
pub sender: User,
|
|
||||||
pub recipient: Room,
|
|
||||||
pub time_sent: DateTime<Utc>,
|
|
||||||
pub time_recieved: DateTime<Utc>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
|
||||||
pub struct Room {
|
|
||||||
pub id: String,
|
|
||||||
pub title: String,
|
|
||||||
pub description: String,
|
|
||||||
pub time_created: DateTime<Utc>,
|
|
||||||
pub members: Vec<String>,
|
|
||||||
pub messages: Vec<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A user for chats, mainly used for authentication
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
||||||
pub struct User {
|
|
||||||
pub id: String,
|
|
||||||
pub name: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
||||||
pub struct KeySet {
|
|
||||||
pub private: String,
|
|
||||||
pub public: String
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Platform {
|
|
||||||
pub id: String,
|
|
||||||
}
|
|
Loading…
Reference in New Issue