imessage_database/tables/
chat.rs1use std::collections::HashMap;
6
7use rusqlite::{Connection, Error, Result, Row, Statement};
8
9use crate::{
10 error::table::TableError,
11 tables::{
12 messages::models::Service,
13 table::{Cacheable, Table, CHAT},
14 },
15};
16
17#[derive(Debug)]
19pub struct Chat {
20 pub rowid: i32,
21 pub chat_identifier: String,
22 pub service_name: Option<String>,
24 pub display_name: Option<String>,
26}
27
28impl Table for Chat {
29 fn from_row(row: &Row) -> Result<Chat> {
30 Ok(Chat {
31 rowid: row.get("rowid")?,
32 chat_identifier: row.get("chat_identifier")?,
33 service_name: row.get("service_name")?,
34 display_name: row.get("display_name").unwrap_or(None),
35 })
36 }
37
38 fn get(db: &Connection) -> Result<Statement, TableError> {
39 db.prepare(&format!("SELECT * from {CHAT}"))
40 .map_err(TableError::Chat)
41 }
42
43 fn extract(chat: Result<Result<Self, Error>, Error>) -> Result<Self, TableError> {
44 match chat {
45 Ok(Ok(chat)) => Ok(chat),
46 Err(why) | Ok(Err(why)) => Err(TableError::Chat(why)),
47 }
48 }
49}
50
51impl Cacheable for Chat {
52 type K = i32;
53 type V = Chat;
54 fn cache(db: &Connection) -> Result<HashMap<Self::K, Self::V>, TableError> {
71 let mut map = HashMap::new();
72
73 let mut statement = Chat::get(db)?;
74
75 let chats = statement
76 .query_map([], |row| Ok(Chat::from_row(row)))
77 .map_err(TableError::Chat)?;
78
79 for chat in chats {
80 let result = Chat::extract(chat)?;
81 map.insert(result.rowid, result);
82 }
83 Ok(map)
84 }
85}
86
87impl Chat {
88 pub fn name(&self) -> &str {
90 match self.display_name() {
91 Some(name) => name,
92 None => &self.chat_identifier,
93 }
94 }
95
96 pub fn display_name(&self) -> Option<&str> {
98 match &self.display_name {
99 Some(name) => {
100 if !name.is_empty() {
101 return Some(name.as_str());
102 }
103 None
104 }
105 None => None,
106 }
107 }
108
109 pub fn service(&self) -> Service {
111 Service::from(self.service_name.as_deref())
112 }
113}