diff --git a/deltachat-ffi/src/dc_array.rs b/deltachat-ffi/src/dc_array.rs index 224c5d06f..4a55cc5db 100644 --- a/deltachat-ffi/src/dc_array.rs +++ b/deltachat-ffi/src/dc_array.rs @@ -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), + Chat(Vec), Locations(Vec), Uint(Vec), } @@ -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> for dc_array_t { } } +impl From> for dc_array_t { + fn from(array: Vec) -> Self { + dc_array_t::Chat(array) + } +} + impl From> for dc_array_t { fn from(array: Vec) -> Self { dc_array_t::Locations(array) diff --git a/src/chat.rs b/src/chat.rs index 988637ee6..d9989fe9c 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -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, -) -> Vec { +) -> Vec { 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) }; diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index 761d0406e..a82622548 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -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, diff --git a/src/message.rs b/src/message.rs index 2305518bd..8ec6b5a82 100644 --- a/src/message.rs +++ b/src/message.rs @@ -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) } }