mirror of
https://github.com/chatmail/core.git
synced 2026-04-29 03:16:29 +03:00
chatlist: resultify get_msg_id, get_summary and get_summary2
Avoid using MsgId::new(0) in place of `None` in the Rust part. Zero ID is only used in FFI part now.
This commit is contained in:
@@ -2318,11 +2318,14 @@ pub unsafe extern "C" fn dc_chatlist_get_msg_id(
|
||||
return 0;
|
||||
}
|
||||
let ffi_list = &*chatlist;
|
||||
ffi_list
|
||||
.list
|
||||
.get_msg_id(index as usize)
|
||||
.map(|msg_id| msg_id.to_u32())
|
||||
.unwrap_or(0)
|
||||
let ctx = &*ffi_list.context;
|
||||
match ffi_list.list.get_msg_id(index as usize) {
|
||||
Ok(msg_id) => msg_id.map_or(0, |msg_id| msg_id.to_u32()),
|
||||
Err(err) => {
|
||||
warn!(ctx, "get_msg_id failed: {}", err);
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -2348,7 +2351,9 @@ pub unsafe extern "C" fn dc_chatlist_get_summary(
|
||||
let lot = ffi_list
|
||||
.list
|
||||
.get_summary(&ctx, index as usize, maybe_chat)
|
||||
.await;
|
||||
.await
|
||||
.log_err(ctx, "get_summary failed")
|
||||
.unwrap_or_default();
|
||||
Box::into_raw(Box::new(lot))
|
||||
})
|
||||
}
|
||||
@@ -2364,9 +2369,16 @@ pub unsafe extern "C" fn dc_chatlist_get_summary2(
|
||||
return ptr::null_mut();
|
||||
}
|
||||
let ctx = &*context;
|
||||
let msg_id = if msg_id == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(MsgId::new(msg_id))
|
||||
};
|
||||
block_on(async move {
|
||||
let lot =
|
||||
Chatlist::get_summary2(&ctx, ChatId::new(chat_id), MsgId::new(msg_id), None).await;
|
||||
let lot = Chatlist::get_summary2(&ctx, ChatId::new(chat_id), msg_id, None)
|
||||
.await
|
||||
.log_err(ctx, "get_summary2 failed")
|
||||
.unwrap_or_default();
|
||||
Box::into_raw(Box::new(lot))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -551,7 +551,7 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
|
||||
},
|
||||
if chat.is_protected() { "🛡️" } else { "" },
|
||||
);
|
||||
let lot = chatlist.get_summary(&context, i, Some(&chat)).await;
|
||||
let lot = chatlist.get_summary(&context, i, Some(&chat)).await?;
|
||||
let statestr = if chat.visibility == ChatVisibility::Archived {
|
||||
" [Archived]"
|
||||
} else {
|
||||
|
||||
@@ -86,7 +86,7 @@ async fn main() {
|
||||
let chats = Chatlist::try_load(&ctx, 0, None, None).await.unwrap();
|
||||
|
||||
for i in 0..chats.len() {
|
||||
let msg = Message::load_from_db(&ctx, chats.get_msg_id(i).unwrap())
|
||||
let msg = Message::load_from_db(&ctx, chats.get_msg_id(i).unwrap().unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
log::info!("[{}] msg: {:?}", i, msg);
|
||||
|
||||
@@ -42,7 +42,7 @@ use crate::stock_str;
|
||||
#[derive(Debug)]
|
||||
pub struct Chatlist {
|
||||
/// Stores pairs of `chat_id, message_id`
|
||||
ids: Vec<(ChatId, MsgId)>,
|
||||
ids: Vec<(ChatId, Option<MsgId>)>,
|
||||
}
|
||||
|
||||
impl Chatlist {
|
||||
@@ -111,7 +111,7 @@ impl Chatlist {
|
||||
|
||||
let process_row = |row: &rusqlite::Row| {
|
||||
let chat_id: ChatId = row.get(0)?;
|
||||
let msg_id: MsgId = row.get(1).unwrap_or_default();
|
||||
let msg_id: Option<MsgId> = row.get(1)?;
|
||||
Ok((chat_id, msg_id))
|
||||
};
|
||||
|
||||
@@ -261,7 +261,7 @@ impl Chatlist {
|
||||
get_last_deaddrop_fresh_msg(context).await?
|
||||
{
|
||||
if !flag_for_forwarding {
|
||||
ids.insert(0, (DC_CHAT_ID_DEADDROP, last_deaddrop_fresh_msg_id));
|
||||
ids.insert(0, (DC_CHAT_ID_DEADDROP, Some(last_deaddrop_fresh_msg_id)));
|
||||
}
|
||||
}
|
||||
add_archived_link_item = true;
|
||||
@@ -271,9 +271,9 @@ impl Chatlist {
|
||||
|
||||
if add_archived_link_item && dc_get_archived_cnt(context).await? > 0 {
|
||||
if ids.is_empty() && flag_add_alldone_hint {
|
||||
ids.push((DC_CHAT_ID_ALLDONE_HINT, MsgId::new(0)));
|
||||
ids.push((DC_CHAT_ID_ALLDONE_HINT, None));
|
||||
}
|
||||
ids.push((DC_CHAT_ID_ARCHIVED_LINK, MsgId::new(0)));
|
||||
ids.push((DC_CHAT_ID_ARCHIVED_LINK, None));
|
||||
}
|
||||
|
||||
Ok(Chatlist { ids })
|
||||
@@ -302,7 +302,7 @@ impl Chatlist {
|
||||
/// Get a single message ID of a chatlist.
|
||||
///
|
||||
/// To get the message object from the message ID, use dc_get_msg().
|
||||
pub fn get_msg_id(&self, index: usize) -> Result<MsgId> {
|
||||
pub fn get_msg_id(&self, index: usize) -> Result<Option<MsgId>> {
|
||||
match self.ids.get(index) {
|
||||
Some((_chat_id, msg_id)) => Ok(*msg_id),
|
||||
None => bail!("Chatlist index out of range"),
|
||||
@@ -323,18 +323,19 @@ impl Chatlist {
|
||||
/// - dc_lot_t::timestamp: the timestamp of the message. 0 if not applicable.
|
||||
/// - dc_lot_t::state: The state of the message as one of the DC_STATE_* constants (see #dc_msg_get_state()).
|
||||
// 0 if not applicable.
|
||||
pub async fn get_summary(&self, context: &Context, index: usize, chat: Option<&Chat>) -> Lot {
|
||||
pub async fn get_summary(
|
||||
&self,
|
||||
context: &Context,
|
||||
index: usize,
|
||||
chat: Option<&Chat>,
|
||||
) -> Result<Lot> {
|
||||
// The summary is created by the chat, not by the last message.
|
||||
// This is because we may want to display drafts here or stuff as
|
||||
// "is typing".
|
||||
// Also, sth. as "No messages" would not work if the summary comes from a message.
|
||||
let (chat_id, lastmsg_id) = match self.ids.get(index) {
|
||||
Some(ids) => ids,
|
||||
None => {
|
||||
let mut ret = Lot::new();
|
||||
ret.text2 = Some("ErrBadChatlistIndex".to_string());
|
||||
return Lot::new();
|
||||
}
|
||||
None => bail!("Chatlist index out of range"),
|
||||
};
|
||||
|
||||
Chatlist::get_summary2(context, *chat_id, *lastmsg_id, chat).await
|
||||
@@ -343,50 +344,50 @@ impl Chatlist {
|
||||
pub async fn get_summary2(
|
||||
context: &Context,
|
||||
chat_id: ChatId,
|
||||
lastmsg_id: MsgId,
|
||||
lastmsg_id: Option<MsgId>,
|
||||
chat: Option<&Chat>,
|
||||
) -> Lot {
|
||||
) -> Result<Lot> {
|
||||
let mut ret = Lot::new();
|
||||
|
||||
let chat_loaded: Chat;
|
||||
let chat = if let Some(chat) = chat {
|
||||
chat
|
||||
} else if let Ok(chat) = Chat::load_from_db(context, chat_id).await {
|
||||
} else {
|
||||
let chat = Chat::load_from_db(context, chat_id).await?;
|
||||
chat_loaded = chat;
|
||||
&chat_loaded
|
||||
} else {
|
||||
return ret;
|
||||
};
|
||||
|
||||
let (lastmsg, lastcontact) =
|
||||
if let Ok(lastmsg) = Message::load_from_db(context, lastmsg_id).await {
|
||||
if lastmsg.from_id == DC_CONTACT_ID_SELF {
|
||||
(Some(lastmsg), None)
|
||||
} else {
|
||||
match chat.typ {
|
||||
Chattype::Group | Chattype::Mailinglist => {
|
||||
let lastcontact =
|
||||
Contact::load_from_db(context, lastmsg.from_id).await.ok();
|
||||
(Some(lastmsg), lastcontact)
|
||||
}
|
||||
Chattype::Single | Chattype::Undefined => (Some(lastmsg), None),
|
||||
}
|
||||
}
|
||||
let (lastmsg, lastcontact) = if let Some(lastmsg_id) = lastmsg_id {
|
||||
let lastmsg = Message::load_from_db(context, lastmsg_id).await?;
|
||||
if lastmsg.from_id == DC_CONTACT_ID_SELF {
|
||||
(Some(lastmsg), None)
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
match chat.typ {
|
||||
Chattype::Group | Chattype::Mailinglist => {
|
||||
let lastcontact =
|
||||
Contact::load_from_db(context, lastmsg.from_id).await.ok();
|
||||
(Some(lastmsg), lastcontact)
|
||||
}
|
||||
Chattype::Single | Chattype::Undefined => (Some(lastmsg), None),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
|
||||
if chat.id.is_archived_link() {
|
||||
ret.text2 = None;
|
||||
} else if lastmsg.is_none() || lastmsg.as_ref().unwrap().from_id == DC_CONTACT_ID_UNDEFINED
|
||||
} else if let Some(mut lastmsg) =
|
||||
lastmsg.filter(|msg| msg.from_id != DC_CONTACT_ID_UNDEFINED)
|
||||
{
|
||||
ret.text2 = Some(stock_str::no_messages(context).await);
|
||||
} else {
|
||||
ret.fill(&mut lastmsg.unwrap(), chat, lastcontact.as_ref(), context)
|
||||
ret.fill(&mut lastmsg, chat, lastcontact.as_ref(), context)
|
||||
.await;
|
||||
} else {
|
||||
ret.text2 = Some(stock_str::no_messages(context).await);
|
||||
}
|
||||
|
||||
ret
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
pub fn get_index_for_id(&self, id: ChatId) -> Option<usize> {
|
||||
@@ -684,7 +685,7 @@ mod tests {
|
||||
chat_id1.set_draft(&t, Some(&mut msg)).await.unwrap();
|
||||
|
||||
let chats = Chatlist::try_load(&t, 0, None, None).await.unwrap();
|
||||
let summary = chats.get_summary(&t, 0, None).await;
|
||||
let summary = chats.get_summary(&t, 0, None).await.unwrap();
|
||||
assert_eq!(summary.get_text2().unwrap(), "foo: bar test"); // the linebreak should be removed from summary
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2295,7 +2295,7 @@ mod tests {
|
||||
let chats = Chatlist::try_load(&t, 0, None, None).await.unwrap();
|
||||
assert_eq!(chats.len(), 1);
|
||||
assert!(chats.get_chat_id(0).is_deaddrop());
|
||||
let chat_id = chat::create_by_msg_id(&t, chats.get_msg_id(0).unwrap())
|
||||
let chat_id = chat::create_by_msg_id(&t, chats.get_msg_id(0).unwrap().unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(!chat_id.is_special());
|
||||
@@ -2330,7 +2330,7 @@ mod tests {
|
||||
.unwrap();
|
||||
let chats = Chatlist::try_load(&t, 0, None, None).await.unwrap();
|
||||
assert_eq!(chats.len(), 2);
|
||||
let chat_id = chat::create_by_msg_id(&t, chats.get_msg_id(0).unwrap())
|
||||
let chat_id = chat::create_by_msg_id(&t, chats.get_msg_id(0).unwrap().unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
let chat = chat::Chat::load_from_db(&t, chat_id).await.unwrap();
|
||||
@@ -2351,7 +2351,7 @@ mod tests {
|
||||
let chats = Chatlist::try_load(&t, 0, None, None).await.unwrap();
|
||||
assert_eq!(chats.len(), 1);
|
||||
assert!(chats.get_chat_id(0).is_deaddrop());
|
||||
let chat_id = chat::create_by_msg_id(&t, chats.get_msg_id(0).unwrap())
|
||||
let chat_id = chat::create_by_msg_id(&t, chats.get_msg_id(0).unwrap().unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
let chat = chat::Chat::load_from_db(&t, chat_id).await.unwrap();
|
||||
@@ -2600,7 +2600,7 @@ mod tests {
|
||||
assert_eq!(contact.get_display_name(), "h2");
|
||||
|
||||
let chats = Chatlist::try_load(&t, 0, None, None).await.unwrap();
|
||||
let msg = Message::load_from_db(&t, chats.get_msg_id(0).unwrap())
|
||||
let msg = Message::load_from_db(&t, chats.get_msg_id(0).unwrap().unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(msg.is_dc_message, MessengerMessage::Yes);
|
||||
@@ -2751,7 +2751,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
let chats = Chatlist::try_load(&t, 0, None, None).await.unwrap();
|
||||
let msg_id = chats.get_msg_id(0).unwrap();
|
||||
let msg_id = chats.get_msg_id(0).unwrap().unwrap();
|
||||
|
||||
// Check that the ndn would be downloaded:
|
||||
let headers = mailparse::parse_mail(raw_ndn).unwrap().headers;
|
||||
@@ -2801,7 +2801,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
let chats = Chatlist::try_load(&t, 0, None, None).await.unwrap();
|
||||
let msg_id = chats.get_msg_id(0).unwrap();
|
||||
let msg_id = chats.get_msg_id(0).unwrap().unwrap();
|
||||
|
||||
let raw = include_bytes!("../test-data/message/gmail_ndn_group.eml");
|
||||
dc_receive_imf(&t, raw, "INBOX", 1, false).await.unwrap();
|
||||
@@ -2834,7 +2834,7 @@ mod tests {
|
||||
.await
|
||||
.unwrap();
|
||||
let chats = Chatlist::try_load(context, 0, None, None).await.unwrap();
|
||||
let msg_id = chats.get_msg_id(0).unwrap();
|
||||
let msg_id = chats.get_msg_id(0).unwrap().unwrap();
|
||||
Message::load_from_db(context, msg_id).await.unwrap()
|
||||
}
|
||||
|
||||
@@ -2884,7 +2884,7 @@ mod tests {
|
||||
let chats = Chatlist::try_load(&t.ctx, 0, None, None).await.unwrap();
|
||||
assert_eq!(chats.len(), 1);
|
||||
|
||||
let chat_id = chat::create_by_msg_id(&t.ctx, chats.get_msg_id(0).unwrap())
|
||||
let chat_id = chat::create_by_msg_id(&t.ctx, chats.get_msg_id(0).unwrap().unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
let chat = chat::Chat::load_from_db(&t.ctx, chat_id).await.unwrap();
|
||||
@@ -2957,7 +2957,7 @@ mod tests {
|
||||
.await
|
||||
.unwrap();
|
||||
let chats = Chatlist::try_load(&t.ctx, 0, None, None).await.unwrap();
|
||||
let chat_id = chat::create_by_msg_id(&t.ctx, chats.get_msg_id(0).unwrap())
|
||||
let chat_id = chat::create_by_msg_id(&t.ctx, chats.get_msg_id(0).unwrap().unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
let chat = Chat::load_from_db(&t.ctx, chat_id).await.unwrap();
|
||||
|
||||
@@ -1806,7 +1806,7 @@ mod tests {
|
||||
|
||||
let chats = Chatlist::try_load(context, 0, None, None).await.unwrap();
|
||||
|
||||
let chat_id = chat::create_by_msg_id(context, chats.get_msg_id(0).unwrap())
|
||||
let chat_id = chat::create_by_msg_id(context, chats.get_msg_id(0).unwrap().unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
||||
@@ -2834,7 +2834,7 @@ On 2020-10-25, Bob wrote:
|
||||
.unwrap();
|
||||
|
||||
let chats = Chatlist::try_load(&t.ctx, 0, None, None).await.unwrap();
|
||||
let msg_id = chats.get_msg_id(0).unwrap();
|
||||
let msg_id = chats.get_msg_id(0).unwrap().unwrap();
|
||||
let msg = Message::load_from_db(&t.ctx, msg_id).await.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
|
||||
@@ -331,7 +331,7 @@ impl TestContext {
|
||||
// The chatlist describes what you see when you open DC, a list of chats and in each of them
|
||||
// the first words of the last message. To get the last message overall, we look at the chat at the top of the
|
||||
// list, which has the index 0.
|
||||
let msg_id = chats.get_msg_id(0).unwrap();
|
||||
let msg_id = chats.get_msg_id(0).unwrap().unwrap();
|
||||
Message::load_from_db(&self.ctx, msg_id)
|
||||
.await
|
||||
.expect("failed to load msg")
|
||||
|
||||
Reference in New Issue
Block a user