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::message::MsgId;
@@ -5,6 +7,7 @@ use crate::message::MsgId;
#[derive(Debug, Clone)]
pub enum dc_array_t {
MsgIds(Vec<MsgId>),
Chat(Vec<ChatItem>),
Locations(Vec<Location>),
Uint(Vec<u32>),
}
@@ -13,6 +16,11 @@ impl dc_array_t {
pub(crate) fn get_id(&self, index: usize) -> u32 {
match self {
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::Uint(array) => array[index],
}
@@ -30,6 +38,7 @@ impl dc_array_t {
pub(crate) fn len(&self) -> usize {
match self {
Self::MsgIds(array) => array.len(),
Self::Chat(array) => array.len(),
Self::Locations(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 {
fn from(array: Vec<Location>) -> Self {
dc_array_t::Locations(array)

View File

@@ -24,6 +24,22 @@ use crate::param::*;
use crate::sql;
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.
///
/// Some chat IDs are reserved to identify special chat types. This
@@ -1580,7 +1596,7 @@ pub async fn get_chat_msgs(
chat_id: ChatId,
flags: u32,
marker1before: Option<MsgId>,
) -> Vec<MsgId> {
) -> Vec<ChatItem> {
match delete_device_expired_messages(context).await {
Err(err) => warn!(context, "Failed to delete expired messages: {}", err),
Ok(messages_deleted) => {
@@ -1603,18 +1619,18 @@ pub async fn get_chat_msgs(
let (curr_id, ts) = row?;
if let Some(marker_id) = marker1before {
if curr_id == marker_id {
ret.push(MsgId::new(DC_MSG_ID_MARKER1));
ret.push(ChatItem::Marker1);
}
}
if (flags & DC_GCM_ADDDAYMARKER) != 0 {
let curr_local_timestamp = ts + cnv_to_local;
let curr_day = curr_local_timestamp / 86400;
if curr_day != last_day {
ret.push(MsgId::new(DC_MSG_ID_DAYMARKER));
ret.push(ChatItem::DayMarker);
last_day = curr_day;
}
}
ret.push(curr_id);
ret.push(ChatItem::Message { msg_id: curr_id });
}
Ok(ret)
};

View File

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

View File

@@ -68,20 +68,6 @@ impl MsgId {
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.
///
/// It means the message is deleted locally, but not on the server
@@ -143,16 +129,7 @@ impl MsgId {
impl std::fmt::Display for MsgId {
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)
}
}