diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 63b1b64c7..2ad87e6c1 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -553,12 +553,23 @@ pub unsafe extern "C" fn dc_get_draft(context: *mut dc_context_t, chat_id: u32) } let context = &*context; - if let Some(message) = chat::get_draft(context, chat_id) { - let ffi_msg = MessageWrapper { context, message }; - return Box::into_raw(Box::new(ffi_msg)); - }; - - ptr::null_mut() + match chat::get_draft(context, chat_id) { + Ok(Some(draft)) => { + let ffi_msg = MessageWrapper { + context, + message: draft, + }; + Box::into_raw(Box::new(ffi_msg)) + } + Ok(None) => ptr::null_mut(), + Err(err) => { + error!( + context, + "Failed to get draft for chat #{}: {}", chat_id, err + ); + ptr::null_mut() + } + } } #[no_mangle] diff --git a/examples/repl/cmdline.rs b/examples/repl/cmdline.rs index 3df2ab041..0951f6123 100644 --- a/examples/repl/cmdline.rs +++ b/examples/repl/cmdline.rs @@ -663,7 +663,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E }, ); log_msglist(context, &msglist)?; - if let Ok(draft) = chat::get_draft(context, sel_chat.get_id()) { + if let Some(draft) = chat::get_draft(context, sel_chat.get_id())? { log_msg(context, "Draft", &draft); } diff --git a/src/chat.rs b/src/chat.rs index 1929b9e02..509eb01eb 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -921,18 +921,13 @@ fn get_draft_msg_id(context: &Context, chat_id: u32) -> u32 { .unwrap_or_default() as u32 } -pub unsafe fn get_draft(context: &Context, chat_id: u32) -> Option { - if chat_id < DC_CHAT_ID_LAST_SPECIAL { - warn!(context, "Invalid chat ID"); - return None; - } - +pub fn get_draft(context: &Context, chat_id: u32) -> Result, Error> { + ensure!(chat_id > DC_CHAT_ID_LAST_SPECIAL, "Invalid chat ID"); let draft_msg_id = get_draft_msg_id(context, chat_id); if draft_msg_id == 0 { - return None; + return Ok(None); } - - Some(dc_msg_load_from_db(context, draft_msg_id).unwrap()) + Ok(Some(dc_msg_load_from_db(context, draft_msg_id)?)) } pub fn get_chat_msgs(context: &Context, chat_id: u32, flags: u32, marker1before: u32) -> Vec { @@ -1879,3 +1874,49 @@ pub fn add_device_msg(context: &Context, chat_id: u32, text: impl AsRef) { msg_id as uintptr_t, ); } + +#[cfg(test)] +mod tests { + use super::*; + + use crate::test_utils::*; + + #[test] + fn test_get_draft_no_draft() { + let t = dummy_context(); + let chat_id = create_by_contact_id(&t.ctx, DC_CONTACT_ID_SELF).unwrap(); + let draft = get_draft(&t.ctx, chat_id).unwrap(); + assert!(draft.is_none()); + } + + #[test] + fn test_get_draft_special_chat_id() { + let t = dummy_context(); + let draft = get_draft(&t.ctx, DC_CHAT_ID_LAST_SPECIAL); + assert!(draft.is_err()); + } + + #[test] + fn test_get_draft_no_chat() { + // This is a weird case, maybe this should be an error but we + // do not get this info from the database currently. + let t = dummy_context(); + let draft = get_draft(&t.ctx, 42).unwrap(); + assert!(draft.is_none()); + } + + #[test] + fn test_get_draft() { + unsafe { + let t = dummy_context(); + let chat_id = create_by_contact_id(&t.ctx, DC_CONTACT_ID_SELF).unwrap(); + let mut msg = dc_msg_new(Viewtype::Text); + dc_msg_set_text(&mut msg, b"hello\x00" as *const u8 as *const libc::c_char); + set_draft(&t.ctx, chat_id, Some(&mut msg)); + let draft = get_draft(&t.ctx, chat_id).unwrap().unwrap(); + let msg_text = dc_msg_get_text(&msg); + let draft_text = dc_msg_get_text(&draft); + assert_eq!(as_str(msg_text), as_str(draft_text)); + } + } +}