1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
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<Delivery>,
pub timestamp: DateTime<Utc>,
// 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<Sqlite> for Delivery {
fn type_info() -> <Sqlite as sqlx::Database>::TypeInfo {
<&str as sqlx::Type<Sqlite>>::type_info()
}
}
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 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)
}
}
// 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<Message>,
}
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 {}
|