-
Notifications
You must be signed in to change notification settings - Fork 108
/
chat.rs
106 lines (93 loc) · 2.94 KB
/
chat.rs
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
/*!
This module represents common (but not all) columns in the `chat` table.
*/
use std::collections::HashMap;
use rusqlite::{Connection, Error, Result, Row, Statement};
use crate::{
error::table::TableError,
tables::table::{Cacheable, Table, CHAT},
};
/// Represents a single row in the `chat` table.
#[derive(Debug)]
pub struct Chat {
pub rowid: i32,
pub chat_identifier: String,
pub service_name: String,
pub display_name: Option<String>,
}
impl Table for Chat {
fn from_row(row: &Row) -> Result<Chat> {
Ok(Chat {
rowid: row.get("rowid")?,
chat_identifier: row.get("chat_identifier")?,
service_name: row.get("service_name")?,
display_name: row.get("display_name").unwrap_or(None),
})
}
fn get(db: &Connection) -> Statement {
db.prepare(&format!("SELECT * from {CHAT}")).unwrap()
}
fn extract(chat: Result<Result<Self, Error>, Error>) -> Result<Self, TableError> {
match chat {
Ok(chat) => match chat {
Ok(ch) => Ok(ch),
// TODO: When does this occur?
Err(why) => Err(TableError::Chat(why)),
},
// TODO: When does this occur?
Err(why) => Err(TableError::Chat(why)),
}
}
}
impl Cacheable for Chat {
type K = i32;
type V = Chat;
/// Generate a hashmap containing each chatroom's ID pointing to the chatroom's metadata.
///
/// These chatroom ID's contain duplicates and must be deduped later once we have all of
/// the participants parsed out. On its own this data is not useful.
///
/// # Example:
///
/// ```
/// use imessage_database::util::dirs::default_db_path;
/// use imessage_database::tables::table::{Cacheable, get_connection};
/// use imessage_database::tables::chat::Chat;
///
/// let db_path = default_db_path();
/// let conn = get_connection(&db_path).unwrap();
/// let chatrooms = Chat::cache(&conn);
/// ```
fn cache(db: &Connection) -> Result<HashMap<Self::K, Self::V>, String> {
let mut map = HashMap::new();
let mut statement = Chat::get(db);
let chats = statement
.query_map([], |row| Ok(Chat::from_row(row)))
.unwrap();
for chat in chats {
let result = Chat::extract(chat)
.map_err(|why| format!("Unable to query {CHAT} table: {why}"))?;
map.insert(result.rowid, result);
}
Ok(map)
}
}
impl Chat {
pub fn name(&self) -> &str {
match &self.display_name() {
Some(name) => name,
None => &self.chat_identifier,
}
}
pub fn display_name(&self) -> Option<&str> {
match &self.display_name {
Some(name) => {
if !name.is_empty() {
return Some(name.as_str());
}
None
}
None => None,
}
}
}