use chrono::{DateTime, Utc}; use jid::JID; use sqlx::Sqlite; use uuid::Uuid; #[derive(Debug, sqlx::FromRow, Clone)] pub struct Message { pub id: Uuid, // does not contain full user information #[sqlx(rename = "from_jid")] // bare jid (for now) pub from: JID, pub delivery: Option, pub timestamp: DateTime, // TODO: originally_from // TODO: message edits // TODO: message timestamp #[sqlx(flatten)] pub body: Body, } #[derive(Debug, Clone, Copy)] pub enum Delivery { Sending, Written, Sent, Delivered, Read, Failed, Queued, } impl sqlx::Type for Delivery { fn type_info() -> ::TypeInfo { <&str as sqlx::Type>::type_info() } } impl sqlx::Decode<'_, Sqlite> for Delivery { fn decode( value: ::ValueRef<'_>, ) -> Result { let value = <&str as sqlx::Decode>::decode(value)?; match value { "sending" => Ok(Self::Sending), "written" => Ok(Self::Written), "sent" => Ok(Self::Sent), "delivered" => Ok(Self::Delivered), "read" => Ok(Self::Read), "failed" => Ok(Self::Failed), "queued" => Ok(Self::Queued), _ => unreachable!(), } } } impl sqlx::Encode<'_, Sqlite> for Delivery { fn encode_by_ref( &self, buf: &mut ::ArgumentBuffer<'_>, ) -> Result { let value = match self { Delivery::Sending => "sending", Delivery::Written => "written", Delivery::Sent => "sent", Delivery::Delivered => "delivered", Delivery::Read => "read", Delivery::Failed => "failed", Delivery::Queued => "queued", }; <&str as sqlx::Encode>::encode(value, buf) } } // TODO: user migrations // pub enum Migrated { // Jabber(User), // Outside, // } #[derive(Debug, sqlx::FromRow, Clone)] pub struct Body { // TODO: rich text, other contents, threads pub body: String, } #[derive(sqlx::FromRow, Debug, Clone)] pub struct Chat { pub correspondent: JID, pub have_chatted: bool, // pub unread_messages: i32, // pub latest_message: Message, // when a new message is received, the chat should be updated, and the new message should be delivered too. // message history is not stored in chat, retreived separately. // pub message_history: Vec, } pub enum ChatUpdate {} impl Chat { pub fn new(correspondent: JID, have_chatted: bool) -> Self { Self { correspondent, have_chatted, } } pub fn correspondent(&self) -> &JID { &self.correspondent } } // TODO: group chats // pub enum Chat { // Direct(DirectChat), // Channel(Channel), // } // pub struct Channel {}