Add ChatItem type

ChatItem can represent markers as enum variants instead of special MsgIds.
This commit is contained in:
Alexander Krotov
2020-06-26 02:58:48 +03:00
committed by link2xt
parent 42f6a7c77c
commit 41fe3db79d
4 changed files with 53 additions and 34 deletions

View File

@@ -1,3 +1,5 @@
use crate::chat::ChatItem;
use crate::constants::{DC_MSG_ID_DAYMARKER, DC_MSG_ID_MARKER1};
use crate::location::Location; use crate::location::Location;
use crate::message::MsgId; use crate::message::MsgId;
@@ -5,6 +7,7 @@ use crate::message::MsgId;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum dc_array_t { pub enum dc_array_t {
MsgIds(Vec<MsgId>), MsgIds(Vec<MsgId>),
Chat(Vec<ChatItem>),
Locations(Vec<Location>), Locations(Vec<Location>),
Uint(Vec<u32>), Uint(Vec<u32>),
} }
@@ -13,6 +16,11 @@ impl dc_array_t {
pub(crate) fn get_id(&self, index: usize) -> u32 { pub(crate) fn get_id(&self, index: usize) -> u32 {
match self { match self {
Self::MsgIds(array) => array[index].to_u32(), Self::MsgIds(array) => array[index].to_u32(),
Self::Chat(array) => match array[index] {
ChatItem::Message { msg_id } => msg_id.to_u32(),
ChatItem::Marker1 => DC_MSG_ID_MARKER1,
ChatItem::DayMarker => DC_MSG_ID_DAYMARKER,
},
Self::Locations(array) => array[index].location_id, Self::Locations(array) => array[index].location_id,
Self::Uint(array) => array[index], Self::Uint(array) => array[index],
} }
@@ -30,6 +38,7 @@ impl dc_array_t {
pub(crate) fn len(&self) -> usize { pub(crate) fn len(&self) -> usize {
match self { match self {
Self::MsgIds(array) => array.len(), Self::MsgIds(array) => array.len(),
Self::Chat(array) => array.len(),
Self::Locations(array) => array.len(), Self::Locations(array) => array.len(),
Self::Uint(array) => array.len(), Self::Uint(array) => array.len(),
} }
@@ -52,6 +61,12 @@ impl From<Vec<MsgId>> for dc_array_t {
} }
} }
impl From<Vec<ChatItem>> for dc_array_t {
fn from(array: Vec<ChatItem>) -> Self {
dc_array_t::Chat(array)
}
}
impl From<Vec<Location>> for dc_array_t { impl From<Vec<Location>> for dc_array_t {
fn from(array: Vec<Location>) -> Self { fn from(array: Vec<Location>) -> Self {
dc_array_t::Locations(array) dc_array_t::Locations(array)

View File

@@ -24,6 +24,22 @@ use crate::param::*;
use crate::sql; use crate::sql;
use crate::stock::StockMessage; use crate::stock::StockMessage;
/// An chat item, such as a message or a marker.
#[derive(Debug, Copy, Clone)]
pub enum ChatItem {
Message {
msg_id: MsgId,
},
/// A marker without inherent meaning. It is inserted before user
/// supplied MsgId.
Marker1,
/// Day marker, separating messages that correspond to different
/// days according to local time.
DayMarker,
}
/// Chat ID, including reserved IDs. /// Chat ID, including reserved IDs.
/// ///
/// Some chat IDs are reserved to identify special chat types. This /// Some chat IDs are reserved to identify special chat types. This
@@ -1580,7 +1596,7 @@ pub async fn get_chat_msgs(
chat_id: ChatId, chat_id: ChatId,
flags: u32, flags: u32,
marker1before: Option<MsgId>, marker1before: Option<MsgId>,
) -> Vec<MsgId> { ) -> Vec<ChatItem> {
match delete_device_expired_messages(context).await { match delete_device_expired_messages(context).await {
Err(err) => warn!(context, "Failed to delete expired messages: {}", err), Err(err) => warn!(context, "Failed to delete expired messages: {}", err),
Ok(messages_deleted) => { Ok(messages_deleted) => {
@@ -1603,18 +1619,18 @@ pub async fn get_chat_msgs(
let (curr_id, ts) = row?; let (curr_id, ts) = row?;
if let Some(marker_id) = marker1before { if let Some(marker_id) = marker1before {
if curr_id == marker_id { if curr_id == marker_id {
ret.push(MsgId::new(DC_MSG_ID_MARKER1)); ret.push(ChatItem::Marker1);
} }
} }
if (flags & DC_GCM_ADDDAYMARKER) != 0 { if (flags & DC_GCM_ADDDAYMARKER) != 0 {
let curr_local_timestamp = ts + cnv_to_local; let curr_local_timestamp = ts + cnv_to_local;
let curr_day = curr_local_timestamp / 86400; let curr_day = curr_local_timestamp / 86400;
if curr_day != last_day { if curr_day != last_day {
ret.push(MsgId::new(DC_MSG_ID_DAYMARKER)); ret.push(ChatItem::DayMarker);
last_day = curr_day; last_day = curr_day;
} }
} }
ret.push(curr_id); ret.push(ChatItem::Message { msg_id: curr_id });
} }
Ok(ret) Ok(ret)
}; };

View File

@@ -1793,7 +1793,7 @@ fn dc_create_incoming_rfc724_mid(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::chat::ChatVisibility; use crate::chat::{ChatItem, ChatVisibility};
use crate::chatlist::Chatlist; use crate::chatlist::Chatlist;
use crate::message::Message; use crate::message::Message;
use crate::test_utils::*; use crate::test_utils::*;
@@ -2118,7 +2118,11 @@ mod tests {
.unwrap(); .unwrap();
let msgs = chat::get_chat_msgs(&t.ctx, group_id, 0, None).await; let msgs = chat::get_chat_msgs(&t.ctx, group_id, 0, None).await;
assert_eq!(msgs.len(), 1); assert_eq!(msgs.len(), 1);
let msg_id = msgs.first().unwrap(); let msg_id = if let ChatItem::Message { msg_id } = msgs.first().unwrap() {
msg_id
} else {
panic!("Wrong item type");
};
let msg = message::Message::load_from_db(&t.ctx, msg_id.clone()) let msg = message::Message::load_from_db(&t.ctx, msg_id.clone())
.await .await
.unwrap(); .unwrap();
@@ -2253,7 +2257,11 @@ mod tests {
); );
let msgs = chat::get_chat_msgs(&t.ctx, chat_id, 0, None).await; let msgs = chat::get_chat_msgs(&t.ctx, chat_id, 0, None).await;
assert_eq!(msgs.len(), 1); assert_eq!(msgs.len(), 1);
let msg_id = msgs.first().unwrap(); let msg_id = if let ChatItem::Message { msg_id } = msgs.first().unwrap() {
msg_id
} else {
panic!("Wrong item type");
};
let msg = message::Message::load_from_db(&t.ctx, msg_id.clone()) let msg = message::Message::load_from_db(&t.ctx, msg_id.clone())
.await .await
.unwrap(); .unwrap();
@@ -2516,9 +2524,12 @@ mod tests {
assert_eq!(msg.state, MessageState::OutFailed); assert_eq!(msg.state, MessageState::OutFailed);
let msgs = chat::get_chat_msgs(&t.ctx, msg.chat_id, 0, None).await; let msgs = chat::get_chat_msgs(&t.ctx, msg.chat_id, 0, None).await;
let last_msg = Message::load_from_db(&t.ctx, *msgs.last().unwrap()) let msg_id = if let ChatItem::Message { msg_id } = msgs.last().unwrap() {
.await msg_id
.unwrap(); } else {
panic!("Wrong item type");
};
let last_msg = Message::load_from_db(&t.ctx, *msg_id).await.unwrap();
assert_eq!( assert_eq!(
last_msg.text, last_msg.text,

View File

@@ -68,20 +68,6 @@ impl MsgId {
self.0 == 0 self.0 == 0
} }
/// Whether the message ID is the special marker1 marker.
///
/// See the docs of the `dc_get_chat_msgs` C API for details.
pub fn is_marker1(self) -> bool {
self.0 == DC_MSG_ID_MARKER1
}
/// Whether the message ID is the special day marker.
///
/// See the docs of the `dc_get_chat_msgs` C API for details.
pub fn is_daymarker(self) -> bool {
self.0 == DC_MSG_ID_DAYMARKER
}
/// Put message into trash chat and delete message text. /// Put message into trash chat and delete message text.
/// ///
/// It means the message is deleted locally, but not on the server /// It means the message is deleted locally, but not on the server
@@ -143,18 +129,9 @@ impl MsgId {
impl std::fmt::Display for MsgId { impl std::fmt::Display for MsgId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// Would be nice if we could use match here, but no computed values in ranges.
if self.0 == DC_MSG_ID_MARKER1 {
write!(f, "Msg#Marker1")
} else if self.0 == DC_MSG_ID_DAYMARKER {
write!(f, "Msg#DayMarker")
} else if self.0 <= DC_MSG_ID_LAST_SPECIAL {
write!(f, "Msg#UnknownSpecial")
} else {
write!(f, "Msg#{}", self.0) write!(f, "Msg#{}", self.0)
} }
} }
}
/// Allow converting [MsgId] to an SQLite type. /// Allow converting [MsgId] to an SQLite type.
/// ///