diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 20b61f50a..2fe346004 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -552,15 +552,24 @@ pub unsafe extern "C" fn dc_get_draft(context: *mut dc_context_t, chat_id: u32) return ptr::null_mut(); // NULL explicitly defined as "no draft" } let context = &*context; - let message = match chat::get_draft(context, chat_id) { - Ok(msg) => msg, - Err(e) => { - error!(context, "Failed to get draft for chat #{}: {}", chat_id, e); - return 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)) } - }; - let ffi_msg = MessageWrapper { context, message }; - 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 8e0923f06..de92a1371 100644 --- a/examples/repl/cmdline.rs +++ b/examples/repl/cmdline.rs @@ -659,7 +659,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 4442cb350..36d11f00c 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -916,12 +916,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) -> Result { +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); - ensure!(draft_msg_id != 0, "Invalid draft message ID"); - - dc_msg_load_from_db(context, draft_msg_id) + if draft_msg_id == 0 { + return Ok(None); + } + 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 { @@ -1862,3 +1863,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)); + } + } +}