diff options
Diffstat (limited to 'filamento/src/chat.rs')
-rw-r--r-- | filamento/src/chat.rs | 101 |
1 files changed, 56 insertions, 45 deletions
diff --git a/filamento/src/chat.rs b/filamento/src/chat.rs index 147c7f7..c02654f 100644 --- a/filamento/src/chat.rs +++ b/filamento/src/chat.rs @@ -1,25 +1,31 @@ +use std::fmt::{Display, Write}; + use chrono::{DateTime, Utc}; -use jid::JID; -use sqlx::Sqlite; +use jid::{BareJID, JID}; +use rusqlite::{ + ToSql, + types::{FromSql, ToSqlOutput, Value}, +}; use uuid::Uuid; -#[derive(Debug, sqlx::FromRow, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +#[cfg_attr(feature = "reactive_stores", derive(reactive_stores::Store))] pub struct Message { pub id: Uuid, // does not contain full user information - #[sqlx(rename = "from_jid")] // bare jid (for now) - pub from: JID, + pub from: BareJID, pub delivery: Option<Delivery>, pub timestamp: DateTime<Utc>, // TODO: originally_from // TODO: message edits // TODO: message timestamp - #[sqlx(flatten)] pub body: Body, } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub enum Delivery { Sending, Written, @@ -30,45 +36,47 @@ pub enum Delivery { Queued, } -impl sqlx::Type<Sqlite> for Delivery { - fn type_info() -> <Sqlite as sqlx::Database>::TypeInfo { - <&str as sqlx::Type<Sqlite>>::type_info() +impl Display for Delivery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Delivery::Sending => f.write_str("sending"), + Delivery::Written => f.write_str("written"), + Delivery::Sent => f.write_str("sent"), + Delivery::Delivered => f.write_str("delivered"), + Delivery::Read => f.write_str("read"), + Delivery::Failed => f.write_str("failed"), + Delivery::Queued => f.write_str("queued"), + } } } -impl sqlx::Decode<'_, Sqlite> for Delivery { - fn decode( - value: <Sqlite as sqlx::Database>::ValueRef<'_>, - ) -> Result<Self, sqlx::error::BoxDynError> { - let value = <&str as sqlx::Decode<Sqlite>>::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 ToSql for Delivery { + fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> { + Ok(match self { + Delivery::Sending => ToSqlOutput::Owned(Value::Text("sending".to_string())), + Delivery::Written => ToSqlOutput::Owned(Value::Text("written".to_string())), + Delivery::Sent => ToSqlOutput::Owned(Value::Text("sent".to_string())), + Delivery::Delivered => ToSqlOutput::Owned(Value::Text("delivered".to_string())), + Delivery::Read => ToSqlOutput::Owned(Value::Text("read".to_string())), + Delivery::Failed => ToSqlOutput::Owned(Value::Text("failed".to_string())), + Delivery::Queued => ToSqlOutput::Owned(Value::Text("queued".to_string())), + }) } } -impl sqlx::Encode<'_, Sqlite> for Delivery { - fn encode_by_ref( - &self, - buf: &mut <Sqlite as sqlx::Database>::ArgumentBuffer<'_>, - ) -> Result<sqlx::encode::IsNull, sqlx::error::BoxDynError> { - 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<Sqlite>>::encode(value, buf) +impl FromSql for Delivery { + fn column_result(value: rusqlite::types::ValueRef<'_>) -> rusqlite::types::FromSqlResult<Self> { + Ok(match value.as_str()? { + "sending" => Self::Sending, + "written" => Self::Written, + "sent" => Self::Sent, + "delivered" => Self::Delivered, + "read" => Self::Read, + "failed" => Self::Failed, + "queued" => Self::Queued, + // TODO: don't have these lol + value => panic!("unexpected subscription `{value}`"), + }) } } @@ -78,15 +86,18 @@ impl sqlx::Encode<'_, Sqlite> for Delivery { // Outside, // } -#[derive(Debug, sqlx::FromRow, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct Body { // TODO: rich text, other contents, threads pub body: String, } -#[derive(sqlx::FromRow, Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +#[cfg_attr(feature = "reactive_stores", derive(reactive_stores::Store))] pub struct Chat { - pub correspondent: JID, + pub correspondent: BareJID, pub have_chatted: bool, // pub unread_messages: i32, // pub latest_message: Message, @@ -98,13 +109,13 @@ pub struct Chat { pub enum ChatUpdate {} impl Chat { - pub fn new(correspondent: JID, have_chatted: bool) -> Self { + pub fn new(correspondent: BareJID, have_chatted: bool) -> Self { Self { correspondent, have_chatted, } } - pub fn correspondent(&self) -> &JID { + pub fn correspondent(&self) -> &BareJID { &self.correspondent } } |