diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index de84d9699..5dc6d343c 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -20,7 +20,7 @@ typedef struct _dc_contact dc_contact_t; typedef struct _dc_lot dc_lot_t; typedef struct _dc_provider dc_provider_t; typedef struct _dc_event dc_event_t; - typedef struct _dc_event_emitter dc_event_emitter_t; +typedef struct _dc_event_emitter dc_event_emitter_t; /** @@ -236,8 +236,11 @@ void dc_event_unref (dc_event_t* event); * - The callback SHOULD return _fast_, for GUI updates etc. you should * post yourself an asynchronous message to your GUI thread, if needed. * - events do not expect a return value, just always return 0. - * @param userdata can be used by the client for any purpuse. He finds it - * later in dc_get_userdata(). + * @param dbfile The file to use to store the database, something like `~/file` won't + * work on all systems, if in doubt, use absolute paths. + * @param blobdir A directory to store the blobs in; a trailing slash is not needed. + * If you pass NULL or the empty string, deltachat-core creates a directory + * beside _dbfile_ with the same name and the suffix `-blobs`. * @param os_name is only for decorative use * and is shown eg. in the `X-Mailer:` header * in the form "Delta Chat Core /". @@ -249,7 +252,7 @@ void dc_event_unref (dc_event_t* event); * The object must be passed to the other context functions * and must be freed using dc_context_unref() after usage. */ -dc_context_t* dc_context_new (void* userdata, const char* os_name); +dc_context_t* dc_context_new (const char* os_name, const char* dbfile, const char* blobdir); /** @@ -266,60 +269,6 @@ dc_context_t* dc_context_new (void* userdata, const char* os_nam */ void dc_context_unref (dc_context_t* context); - -/** - * Get user data associated with a context object. - * - * @memberof dc_context_t - * @param context The context object as created by dc_context_new(). - * @return User data, this is the second parameter given to dc_context_new(). - */ -void* dc_get_userdata (dc_context_t* context); - - -/** - * Open context database. If the given file does not exist, it is - * created and can be set up using dc_set_config() afterwards. - * - * @memberof dc_context_t - * @param context The context object as created by dc_context_new(). - * @param dbfile The file to use to store the database, something like `~/file` won't - * work on all systems, if in doubt, use absolute paths. - * @param blobdir A directory to store the blobs in; a trailing slash is not needed. - * If you pass NULL or the empty string, deltachat-core creates a directory - * beside _dbfile_ with the same name and the suffix `-blobs`. - * @return 1 on success, 0 on failure - * eg. if the file is not writable - * or if there is already a database opened for the context. - */ -int dc_open (dc_context_t* context, const char* dbfile, const char* blobdir); - - -/** - * Close context database opened by dc_open(). - * Before this, connections to SMTP and IMAP are closed; these connections - * are started automatically as needed eg. by sending for fetching messages. - * This function is also implicitly called by dc_context_unref(). - * Multiple calls to this functions are okay, the function takes care not - * to free objects twice. - * - * @memberof dc_context_t - * @param context The context object as created by dc_context_new(). - * @return None. - */ -void dc_close (dc_context_t* context); - - -/** - * Check if the context database is open. - * - * @memberof dc_context_t - * @param context The context object as created by dc_context_new(). - * @return 0=context is not open, 1=context is open. - */ -int dc_is_open (const dc_context_t* context); - - /** * Get the blob directory. * diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 203b70ac4..f996db069 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -18,12 +18,9 @@ use std::convert::TryInto; use std::fmt::Write; use std::ptr; use std::str::FromStr; -use std::sync::{Arc, RwLock}; use std::time::{Duration, SystemTime}; -use anyhow::anyhow; -use async_std::task::block_on; -use libc::uintptr_t; +use async_std::task::{block_on, spawn}; use num_traits::{FromPrimitive, ToPrimitive}; use deltachat::chat::{ChatId, ChatVisibility, MuteDuration}; @@ -52,156 +49,44 @@ use self::string::*; // dc_context_t -/// The FFI context struct. -/// -/// This structure represents the [Context] on the FFI interface. -/// Since it is returned by [dc_context_new] before it is initialised -/// by [dc_open] it needs to store the actual [Context] in an [Option] -/// and protected by an [RwLock]. Other than that it needs to store -/// the data which is passed into [dc_context_new]. -pub struct ContextWrapper { - userdata: *mut libc::c_void, - os_name: String, - inner: Arc>>, -} - -unsafe impl Send for ContextWrapper {} -unsafe impl Sync for ContextWrapper {} - -/// Callback function that should be given to [dc_context_new]. -/// -/// @memberof [dc_context_t] -/// @param context The context object as returned by [dc_context_new]. -/// @param event one of the @ref DC_EVENT constants -/// @param data1 depends on the event parameter -/// @param data2 depends on the event parameter -/// @return return 0 unless stated otherwise in the event parameter documentation -pub type dc_callback_t = - unsafe extern "C" fn(_: &dc_context_t, _: i32, _: uintptr_t, _: uintptr_t) -> uintptr_t; - /// Struct representing the deltachat context. -/// -/// See [ContextWrapper] for implementation details. -pub type dc_context_t = ContextWrapper; - -impl ContextWrapper { - /// Log a warning on the FFI context. - /// - /// Like [error] but logs as a warning which only goes to the - /// logfile rather than being shown directly to the user. - unsafe fn warning(&self, msg: &str) { - self.with_inner(|ctx| { - ctx.emit_event(Event::Warning(msg.to_string())); - }) - .unwrap(); - } - - /// Unlock the context and execute a closure with it. - /// - /// This unlocks the context and gets a read lock. The Rust - /// [Context] object it passed as only argument to the closure - /// which can now do Rust API calls using it. The return value of - /// the closure will be returned by this function. When the - /// closure returns the read lock is released. - /// - /// If the context is not open an error is logged via the callback - /// and `Err(())` is returned. - /// - /// This function returns a [Result] allowing the caller to supply - /// the appropriate return value for an error return since this - /// differs for various functions on the FFI API: sometimes 0, - /// NULL, an empty string etc. - fn with_inner(&self, ctxfn: F) -> Result - where - F: FnOnce(&Context) -> T, - { - let guard = self.inner.read().unwrap(); - match guard.as_ref() { - Some(ref ctx) => Ok(ctxfn(ctx)), - None => { - eprintln!("ignoring careless call to non open context"); - Err(()) - } - } - } - - fn is_open(&self) -> bool { - self.inner.read().unwrap().is_some() - } -} - -macro_rules! with_inner_async { - ($ctx:expr, $name:ident, $block:expr) => {{ - let l = $ctx.inner.clone(); - let lock = l.read().unwrap(); - block_on(async move { - match lock.as_ref() { - Some(ctx) => { - let $name = ctx; - let res = $block.await; - Ok(res) - } - None => { - eprintln!("ignoring careless call to non open context"); - Err(()) - } - } - }) - }}; -} - -macro_rules! with_inner_spawn { - ($ctx:expr, $name:ident, $block:expr) => {{ - let l = $ctx.inner.clone(); - let lock = l.read().unwrap(); - match lock.as_ref() { - Some(ctx) => { - let $name = ctx.clone(); - async_std::task::spawn(async move { $block.await }); - Ok(()) - } - None => { - eprintln!("ignoring careless call to non open context"); - Err(()) - } - } - }}; -} -macro_rules! try_inner_async { - ($ctx:expr, $name:ident, $block:expr) => {{ - let l = $ctx.inner.clone(); - let lock = l.read().unwrap(); - block_on(async move { - match lock.as_ref() { - Some(ctx) => { - let $name = ctx; - $block.await - } - None => Err(anyhow!("context not open")), - } - }) - }}; -} +pub type dc_context_t = Context; #[no_mangle] pub unsafe extern "C" fn dc_context_new( - userdata: *mut libc::c_void, os_name: *const libc::c_char, + dbfile: *const libc::c_char, + blobdir: *const libc::c_char, ) -> *mut dc_context_t { setup_panic!(); + if dbfile.is_null() { + eprintln!("ignoring careless call to dc_context_new()"); + return ptr::null_mut(); + } + let os_name = if os_name.is_null() { String::from("DcFFI") } else { to_string_lossy(os_name) }; - let ffi_ctx = ContextWrapper { - userdata, - os_name, - inner: Arc::new(RwLock::new(None)), - }; - Box::into_raw(Box::new(ffi_ctx)) + let ctx = if blobdir.is_null() || *blobdir == 0 { + block_on(Context::new(os_name, as_path(dbfile).to_path_buf().into())) + } else { + block_on(Context::with_blobdir( + os_name, + as_path(dbfile).to_path_buf().into(), + as_path(blobdir).to_path_buf().into(), + )) + }; + match ctx { + Ok(ctx) => Box::into_raw(Box::new(ctx)), + Err(err) => { + eprintln!("failed to create context: {}", err); + ptr::null_mut() + } + } } /// Release the context structure. @@ -213,72 +98,7 @@ pub unsafe extern "C" fn dc_context_unref(context: *mut dc_context_t) { eprintln!("ignoring careless call to dc_context_unref()"); return; } - let ffi_context = &mut *context; - Box::from_raw(ffi_context); -} - -#[no_mangle] -pub unsafe extern "C" fn dc_get_userdata(context: *mut dc_context_t) -> *mut libc::c_void { - if context.is_null() { - eprintln!("ignoring careless call to dc_get_userdata()"); - return ptr::null_mut(); - } - let ffi_context = &mut *context; - ffi_context.userdata -} - -#[no_mangle] -pub unsafe extern "C" fn dc_open( - context: *mut dc_context_t, - dbfile: *const libc::c_char, - blobdir: *const libc::c_char, -) -> libc::c_int { - if context.is_null() || dbfile.is_null() { - eprintln!("ignoring careless call to dc_open()"); - return 0; - } - let ffi_context = &*context; - - let ctx = if blobdir.is_null() || *blobdir == 0 { - block_on(Context::new( - ffi_context.os_name.clone(), - as_path(dbfile).to_path_buf().into(), - )) - } else { - block_on(Context::with_blobdir( - ffi_context.os_name.clone(), - as_path(dbfile).to_path_buf().into(), - as_path(blobdir).to_path_buf().into(), - )) - }; - match ctx { - Ok(ctx) => { - let mut inner_guard = ffi_context.inner.write().unwrap(); - *inner_guard = Some(ctx); - 1 - } - Err(_) => 0, - } -} - -#[no_mangle] -pub unsafe extern "C" fn dc_close(context: *mut dc_context_t) { - if context.is_null() { - eprintln!("ignoring careless call to dc_close()"); - return; - } - let ffi_context = &mut *context; - ffi_context.inner.write().unwrap().take(); -} - -#[no_mangle] -pub unsafe extern "C" fn dc_is_open(context: *mut dc_context_t) -> libc::c_int { - if context.is_null() { - eprintln!("ignoring careless call to dc_is_open()"); - return 0; - } - let ffi_context = &*context; - ffi_context.is_open() as libc::c_int + Box::from_raw(context); } #[no_mangle] @@ -287,10 +107,8 @@ pub unsafe extern "C" fn dc_get_blobdir(context: *mut dc_context_t) -> *mut libc eprintln!("ignoring careless call to dc_get_blobdir()"); return "".strdup(); } - let ffi_context = &*context; - ffi_context - .with_inner(|ctx| ctx.get_blobdir().to_string_lossy().strdup()) - .unwrap_or_else(|_| "".strdup()) + let ctx = &*context; + ctx.get_blobdir().to_string_lossy().strdup() } #[no_mangle] @@ -303,18 +121,17 @@ pub unsafe extern "C" fn dc_set_config( eprintln!("ignoring careless call to dc_set_config()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; match config::Config::from_str(&to_string_lossy(key)) { // When ctx.set_config() fails it already logged the error. // TODO: Context::set_config() should not log this - Ok(key) => with_inner_async!(ffi_context, ctx, async move { + Ok(key) => block_on(async move { ctx.set_config(key, to_opt_string_lossy(value).as_ref().map(|x| x.as_str())) .await .is_ok() as libc::c_int - }) - .unwrap_or(0), + }), Err(_) => { - ffi_context.warning("dc_set_config(): invalid key"); + warn!(ctx, "dc_set_config(): invalid key"); 0 } } @@ -329,14 +146,11 @@ pub unsafe extern "C" fn dc_get_config( eprintln!("ignoring careless call to dc_get_config()"); return "".strdup(); } - let ffi_context = &*context; + let ctx = &*context; match config::Config::from_str(&to_string_lossy(key)) { - Ok(key) => with_inner_async!(ffi_context, ctx, async move { - ctx.get_config(key).await.unwrap_or_default().strdup() - }) - .unwrap_or_else(|_| "".strdup()), + Ok(key) => block_on(async move { ctx.get_config(key).await.unwrap_or_default().strdup() }), Err(_) => { - ffi_context.warning("dc_get_config(): invalid key"); + warn!(ctx, "dc_get_config(): invalid key"); "".strdup() } } @@ -353,9 +167,9 @@ pub unsafe extern "C" fn dc_set_stock_translation( return 0; } let msg = to_string_lossy(stock_msg); - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { match StockMessage::from_u32(stock_id) { Some(id) => match ctx.set_stock_translation(id, msg).await { Ok(()) => 1, @@ -370,7 +184,6 @@ pub unsafe extern "C" fn dc_set_stock_translation( } } }) - .unwrap_or(0) } #[no_mangle] @@ -383,9 +196,9 @@ pub unsafe extern "C" fn dc_set_config_from_qr( return 0; } let qr = to_string_lossy(qr); - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { match qr::set_config_from_qr(&ctx, &qr).await { Ok(()) => 1, Err(err) => { @@ -394,7 +207,6 @@ pub unsafe extern "C" fn dc_set_config_from_qr( } } }) - .unwrap_or(0) } #[no_mangle] @@ -403,14 +215,9 @@ pub unsafe extern "C" fn dc_get_info(context: *mut dc_context_t) -> *mut libc::c eprintln!("ignoring careless call to dc_get_info()"); return "".strdup(); } - let ffi_context = &*context; - - let guard = ffi_context.inner.read().unwrap(); + let ctx = &*context; block_on(async move { - let info = match guard.as_ref() { - Some(ref ctx) => ctx.get_info().await, - None => context::get_info(), - }; + let info = ctx.get_info().await; render_info(info).unwrap_or_default().strdup() }) } @@ -436,17 +243,16 @@ pub unsafe extern "C" fn dc_get_oauth2_url( eprintln!("ignoring careless call to dc_get_oauth2_url()"); return ptr::null_mut(); // NULL explicitly defined as "unknown" } - let ffi_context = &*context; + let ctx = &*context; let addr = to_string_lossy(addr); let redirect = to_string_lossy(redirect); - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { match oauth2::dc_get_oauth2_url(&ctx, addr, redirect).await { Some(res) => res.strdup(), None => ptr::null_mut(), } }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -456,14 +262,9 @@ pub unsafe extern "C" fn dc_configure(context: *mut dc_context_t) { return; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_spawn!(ffi_context, ctx, async move { - ctx.configure() - .await - .log_err(ffi_context, "Configure failed") - }) - .ok(); + spawn(async move { ctx.configure().await.log_err(ctx, "Configure failed") }); } #[no_mangle] @@ -472,12 +273,9 @@ pub unsafe extern "C" fn dc_is_configured(context: *mut dc_context_t) -> libc::c eprintln!("ignoring careless call to dc_is_configured()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { - ctx.is_configured().await as libc::c_int - }) - .unwrap_or(0) + block_on(async move { ctx.is_configured().await as libc::c_int }) } #[no_mangle] @@ -485,18 +283,19 @@ pub unsafe extern "C" fn dc_start_io(context: *mut dc_context_t) { if context.is_null() { return; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, { ctx.start_io() }).unwrap_or(()) + block_on({ ctx.start_io() }) } + #[no_mangle] pub unsafe extern "C" fn dc_is_io_running(context: *mut dc_context_t) -> libc::c_int { if context.is_null() { return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, { ctx.is_io_running() }).unwrap_or_default() as libc::c_int + block_on({ ctx.is_io_running() }) as libc::c_int } #[no_mangle] @@ -659,10 +458,8 @@ pub unsafe extern "C" fn dc_get_event_emitter( eprintln!("ignoring careless call to dc_get_event_emitter()"); return ptr::null_mut(); } - let ffi_context = &*context; - ffi_context - .with_inner(|ctx| Box::into_raw(Box::new(ctx.get_event_emitter()))) - .unwrap_or_else(|_| ptr::null_mut()) + let ctx = &*context; + Box::into_raw(Box::new(ctx.get_event_emitter())) } #[no_mangle] @@ -694,12 +491,11 @@ pub unsafe extern "C" fn dc_stop_io(context: *mut dc_context_t) { eprintln!("ignoring careless call to dc_shutdown()"); return; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { ctx.stop_io().await; }) - .unwrap_or(()) } #[no_mangle] @@ -708,9 +504,9 @@ pub unsafe extern "C" fn dc_maybe_network(context: *mut dc_context_t) { eprintln!("ignoring careless call to dc_maybe_network()"); return; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { ctx.maybe_network().await }).unwrap_or(()) + block_on(async move { ctx.maybe_network().await }) } #[no_mangle] @@ -724,8 +520,8 @@ pub unsafe extern "C" fn dc_preconfigure_keypair( eprintln!("ignoring careless call to dc_preconfigure_keypair()"); return 0; } - let ffi_context = &*context; - try_inner_async!(ffi_context, ctx, async move { + let ctx = &*context; + block_on(async move { let addr = dc_tools::EmailAddress::new(&to_string_lossy(addr))?; let public = key::SignedPublicKey::from_base64(&to_string_lossy(public_data))?; let secret = key::SignedSecretKey::from_base64(&to_string_lossy(secret_data))?; @@ -735,9 +531,9 @@ pub unsafe extern "C" fn dc_preconfigure_keypair( secret, }; key::store_self_keypair(&ctx, &keypair, key::KeyPairUse::Default).await?; - Ok(1) + Ok::<_, anyhow::Error>(1) }) - .log_err(ffi_context, "Failed to save keypair") + .log_err(ctx, "Failed to save keypair") .unwrap_or(0) } @@ -752,12 +548,12 @@ pub unsafe extern "C" fn dc_get_chatlist( eprintln!("ignoring careless call to dc_get_chatlist()"); return ptr::null_mut(); } - let ffi_context = &*context; + let ctx = &*context; let qs = to_opt_string_lossy(query_str); let qi = if query_id == 0 { None } else { Some(query_id) }; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { match chatlist::Chatlist::try_load( &ctx, flags as usize, @@ -773,7 +569,6 @@ pub unsafe extern "C" fn dc_get_chatlist( Err(_) => ptr::null_mut(), } }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -782,16 +577,15 @@ pub unsafe extern "C" fn dc_create_chat_by_msg_id(context: *mut dc_context_t, ms eprintln!("ignoring careless call to dc_create_chat_by_msg_id()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { chat::create_by_msg_id(&ctx, MsgId::new(msg_id)) .await - .log_err(ffi_context, "Failed to create chat from msg_id") + .log_err(ctx, "Failed to create chat from msg_id") .map(|id| id.to_u32()) .unwrap_or(0) }) - .unwrap_or(0) } #[no_mangle] @@ -803,16 +597,15 @@ pub unsafe extern "C" fn dc_create_chat_by_contact_id( eprintln!("ignoring careless call to dc_create_chat_by_contact_id()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { chat::create_by_contact_id(&ctx, contact_id) .await - .log_err(ffi_context, "Failed to create chat from contact_id") + .log_err(ctx, "Failed to create chat from contact_id") .map(|id| id.to_u32()) .unwrap_or(0) }) - .unwrap_or(0) } #[no_mangle] @@ -824,16 +617,15 @@ pub unsafe extern "C" fn dc_get_chat_id_by_contact_id( eprintln!("ignoring careless call to dc_get_chat_id_by_contact_id()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { chat::get_by_contact_id(&ctx, contact_id) .await - .log_err(ffi_context, "Failed to get chat for contact_id") + .log_err(ctx, "Failed to get chat for contact_id") .map(|id| id.to_u32()) .unwrap_or(0) }) - .unwrap_or(0) } #[no_mangle] @@ -846,16 +638,15 @@ pub unsafe extern "C" fn dc_prepare_msg( eprintln!("ignoring careless call to dc_prepare_msg()"); return 0; } - let ffi_context = &mut *context; + let ctx = &mut *context; let ffi_msg: &mut MessageWrapper = &mut *msg; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { chat::prepare_msg(&ctx, ChatId::new(chat_id), &mut ffi_msg.message) .await .unwrap_or_log_default(&ctx, "Failed to prepare message") }) - .map(|msg_id| msg_id.to_u32()) - .unwrap_or(0) + .to_u32() } #[no_mangle] @@ -868,16 +659,15 @@ pub unsafe extern "C" fn dc_send_msg( eprintln!("ignoring careless call to dc_send_msg()"); return 0; } - let ffi_context = &mut *context; + let ctx = &mut *context; let ffi_msg = &mut *msg; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { chat::send_msg(&ctx, ChatId::new(chat_id), &mut ffi_msg.message) .await .unwrap_or_log_default(&ctx, "Failed to send message") }) - .map(|msg_id| msg_id.to_u32()) - .unwrap_or(0) + .to_u32() } #[no_mangle] @@ -890,16 +680,15 @@ pub unsafe extern "C" fn dc_send_text_msg( eprintln!("ignoring careless call to dc_send_text_msg()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; let text_to_send = to_string_lossy(text_to_send); - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { chat::send_text_msg(&ctx, ChatId::new(chat_id), text_to_send) .await .map(|msg_id| msg_id.to_u32()) .unwrap_or_log_default(&ctx, "Failed to send text message") }) - .unwrap_or(0) } #[no_mangle] @@ -912,7 +701,7 @@ pub unsafe extern "C" fn dc_set_draft( eprintln!("ignoring careless call to dc_set_draft()"); return; } - let ffi_context = &*context; + let ctx = &*context; let msg = if msg.is_null() { None } else { @@ -920,7 +709,7 @@ pub unsafe extern "C" fn dc_set_draft( Some(&mut ffi_msg.message) }; - with_inner_async!(ffi_context, ctx, ChatId::new(chat_id).set_draft(&ctx, msg)).unwrap_or(()) + block_on(ChatId::new(chat_id).set_draft(&ctx, msg)) } #[no_mangle] @@ -933,7 +722,7 @@ pub unsafe extern "C" fn dc_add_device_msg( eprintln!("ignoring careless call to dc_add_device_msg()"); return 0; } - let ffi_context = &mut *context; + let ctx = &mut *context; let msg = if msg.is_null() { None } else { @@ -941,7 +730,7 @@ pub unsafe extern "C" fn dc_add_device_msg( Some(&mut ffi_msg.message) }; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { chat::add_device_msg( &ctx, to_opt_string_lossy(label).as_ref().map(|x| x.as_str()), @@ -950,8 +739,7 @@ pub unsafe extern "C" fn dc_add_device_msg( .await .unwrap_or_log_default(&ctx, "Failed to add device message") }) - .map(|msg_id| msg_id.to_u32()) - .unwrap_or(0) + .to_u32() } #[no_mangle] @@ -960,14 +748,13 @@ pub unsafe extern "C" fn dc_update_device_chats(context: *mut dc_context_t) { eprintln!("ignoring careless call to dc_update_device_chats()"); return; } - let ffi_context = &mut *context; + let ctx = &mut *context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { ctx.update_device_chats() .await .unwrap_or_log_default(&ctx, "Failed to add device message") }) - .unwrap_or(()) } #[no_mangle] @@ -979,14 +766,13 @@ pub unsafe extern "C" fn dc_was_device_msg_ever_added( eprintln!("ignoring careless call to dc_was_device_msg_ever_added()"); return 0; } - let ffi_context = &mut *context; + let ctx = &mut *context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { chat::was_device_msg_ever_added(&ctx, &to_string_lossy(label)) .await .unwrap_or(false) as libc::c_int }) - .unwrap_or(0) } #[no_mangle] @@ -995,9 +781,9 @@ pub unsafe extern "C" fn dc_get_draft(context: *mut dc_context_t, chat_id: u32) eprintln!("ignoring careless call to dc_get_draft()"); return ptr::null_mut(); // NULL explicitly defined as "no draft" } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { match ChatId::new(chat_id).get_draft(&ctx).await { Ok(Some(draft)) => { let ffi_msg = MessageWrapper { @@ -1013,7 +799,6 @@ pub unsafe extern "C" fn dc_get_draft(context: *mut dc_context_t, chat_id: u32) } } }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -1027,14 +812,14 @@ pub unsafe extern "C" fn dc_get_chat_msgs( eprintln!("ignoring careless call to dc_get_chat_msgs()"); return ptr::null_mut(); } - let ffi_context = &*context; + let ctx = &*context; let marker_flag = if marker1before <= DC_MSG_ID_LAST_SPECIAL { None } else { Some(MsgId::new(marker1before)) }; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { let arr = dc_array_t::from( chat::get_chat_msgs(&ctx, ChatId::new(chat_id), flags, marker_flag) .await @@ -1044,7 +829,6 @@ pub unsafe extern "C" fn dc_get_chat_msgs( ); Box::into_raw(Box::new(arr)) }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -1053,12 +837,9 @@ pub unsafe extern "C" fn dc_get_msg_cnt(context: *mut dc_context_t, chat_id: u32 eprintln!("ignoring careless call to dc_get_msg_cnt()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { - ChatId::new(chat_id).get_msg_cnt(&ctx).await as libc::c_int - }) - .unwrap_or(0) + block_on(async move { ChatId::new(chat_id).get_msg_cnt(&ctx).await as libc::c_int }) } #[no_mangle] @@ -1070,12 +851,9 @@ pub unsafe extern "C" fn dc_get_fresh_msg_cnt( eprintln!("ignoring careless call to dc_get_fresh_msg_cnt()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { - ChatId::new(chat_id).get_fresh_msg_cnt(&ctx).await as libc::c_int - }) - .unwrap_or(0) + block_on(async move { ChatId::new(chat_id).get_fresh_msg_cnt(&ctx).await as libc::c_int }) } #[no_mangle] @@ -1088,13 +866,12 @@ pub unsafe extern "C" fn dc_estimate_deletion_cnt( eprintln!("ignoring careless call to dc_estimate_deletion_cnt()"); return 0; } - let ffi_context = &*context; - with_inner_async!(ffi_context, ctx, async move { + let ctx = &*context; + block_on(async move { message::estimate_deletion_cnt(ctx, from_server != 0, seconds) .await .unwrap_or(0) as libc::c_int }) - .unwrap_or(0) } #[no_mangle] @@ -1105,9 +882,9 @@ pub unsafe extern "C" fn dc_get_fresh_msgs( eprintln!("ignoring careless call to dc_get_fresh_msgs()"); return ptr::null_mut(); } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { let arr = dc_array_t::from( ctx.get_fresh_msgs() .await @@ -1117,7 +894,6 @@ pub unsafe extern "C" fn dc_get_fresh_msgs( ); Box::into_raw(Box::new(arr)) }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -1126,15 +902,14 @@ pub unsafe extern "C" fn dc_marknoticed_chat(context: *mut dc_context_t, chat_id eprintln!("ignoring careless call to dc_marknoticed_chat()"); return; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { chat::marknoticed_chat(&ctx, ChatId::new(chat_id)) .await - .log_err(ffi_context, "Failed marknoticed chat") + .log_err(ctx, "Failed marknoticed chat") .unwrap_or(()) }) - .unwrap_or(()) } #[no_mangle] @@ -1143,15 +918,14 @@ pub unsafe extern "C" fn dc_marknoticed_all_chats(context: *mut dc_context_t) { eprintln!("ignoring careless call to dc_marknoticed_all_chats()"); return; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { chat::marknoticed_all_chats(&ctx) .await - .log_err(ffi_context, "Failed marknoticed all chats") + .log_err(ctx, "Failed marknoticed all chats") .unwrap_or(()) }) - .unwrap_or(()) } fn from_prim(s: S) -> Option @@ -1174,14 +948,14 @@ pub unsafe extern "C" fn dc_get_chat_media( eprintln!("ignoring careless call to dc_get_chat_media()"); return ptr::null_mut(); } - let ffi_context = &*context; + let ctx = &*context; let msg_type = from_prim(msg_type).expect(&format!("invalid msg_type = {}", msg_type)); let or_msg_type2 = from_prim(or_msg_type2).expect(&format!("incorrect or_msg_type2 = {}", or_msg_type2)); let or_msg_type3 = from_prim(or_msg_type3).expect(&format!("incorrect or_msg_type3 = {}", or_msg_type3)); - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { let arr = dc_array_t::from( chat::get_chat_media( &ctx, @@ -1197,7 +971,6 @@ pub unsafe extern "C" fn dc_get_chat_media( ); Box::into_raw(Box::new(arr)) }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -1219,14 +992,14 @@ pub unsafe extern "C" fn dc_get_next_media( chat::Direction::Forward }; - let ffi_context = &*context; + let ctx = &*context; let msg_type = from_prim(msg_type).expect(&format!("invalid msg_type = {}", msg_type)); let or_msg_type2 = from_prim(or_msg_type2).expect(&format!("incorrect or_msg_type2 = {}", or_msg_type2)); let or_msg_type3 = from_prim(or_msg_type3).expect(&format!("incorrect or_msg_type3 = {}", or_msg_type3)); - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { chat::get_next_media( &ctx, MsgId::new(msg_id), @@ -1239,7 +1012,6 @@ pub unsafe extern "C" fn dc_get_next_media( .map(|msg_id| msg_id.to_u32()) .unwrap_or(0) }) - .unwrap_or(0) } #[no_mangle] @@ -1252,27 +1024,27 @@ pub unsafe extern "C" fn dc_set_chat_visibility( eprintln!("ignoring careless call to dc_set_chat_visibility()"); return; } - let ffi_context = &*context; + let ctx = &*context; let visibility = match archive { 0 => ChatVisibility::Normal, 1 => ChatVisibility::Archived, 2 => ChatVisibility::Pinned, _ => { - ffi_context.warning( + warn!( + ctx, "ignoring careless call to dc_set_chat_visibility(): unknown archived state", ); return; } }; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { ChatId::new(chat_id) .set_visibility(&ctx, visibility) .await - .log_err(ffi_context, "Failed setting chat visibility") + .log_err(ctx, "Failed setting chat visibility") .unwrap_or(()) }) - .unwrap_or(()) } #[no_mangle] @@ -1281,16 +1053,15 @@ pub unsafe extern "C" fn dc_delete_chat(context: *mut dc_context_t, chat_id: u32 eprintln!("ignoring careless call to dc_delete_chat()"); return; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { ChatId::new(chat_id) .delete(&ctx) .await - .log_err(ffi_context, "Failed chat delete") + .log_err(ctx, "Failed chat delete") .unwrap_or(()) }) - .unwrap_or(()) } #[no_mangle] @@ -1302,13 +1073,12 @@ pub unsafe extern "C" fn dc_get_chat_contacts( eprintln!("ignoring careless call to dc_get_chat_contacts()"); return ptr::null_mut(); } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { let arr = dc_array_t::from(chat::get_chat_contacts(&ctx, ChatId::new(chat_id)).await); Box::into_raw(Box::new(arr)) }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -1321,9 +1091,9 @@ pub unsafe extern "C" fn dc_search_msgs( eprintln!("ignoring careless call to dc_search_msgs()"); return ptr::null_mut(); } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { let arr = dc_array_t::from( ctx.search_msgs(ChatId::new(chat_id), to_string_lossy(query)) .await @@ -1333,7 +1103,6 @@ pub unsafe extern "C" fn dc_search_msgs( ); Box::into_raw(Box::new(arr)) }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -1342,9 +1111,9 @@ pub unsafe extern "C" fn dc_get_chat(context: *mut dc_context_t, chat_id: u32) - eprintln!("ignoring careless call to dc_get_chat()"); return ptr::null_mut(); } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { match chat::Chat::load_from_db(&ctx, ChatId::new(chat_id)).await { Ok(chat) => { let ffi_chat = ChatWrapper { context, chat }; @@ -1353,7 +1122,6 @@ pub unsafe extern "C" fn dc_get_chat(context: *mut dc_context_t, chat_id: u32) - Err(_) => ptr::null_mut(), } }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -1366,21 +1134,20 @@ pub unsafe extern "C" fn dc_create_group_chat( eprintln!("ignoring careless call to dc_create_group_chat()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; let verified = if let Some(s) = contact::VerifiedStatus::from_i32(verified) { s } else { return 0; }; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { chat::create_group_chat(&ctx, verified, to_string_lossy(name)) .await - .log_err(ffi_context, "Failed to create group chat") + .log_err(ctx, "Failed to create group chat") .map(|id| id.to_u32()) .unwrap_or(0) }) - .unwrap_or(0) } #[no_mangle] @@ -1393,15 +1160,10 @@ pub unsafe extern "C" fn dc_is_contact_in_chat( eprintln!("ignoring careless call to dc_is_contact_in_chat()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!( - ffi_context, - ctx, - chat::is_contact_in_chat(&ctx, ChatId::new(chat_id), contact_id) - ) - .unwrap_or_default() - .into() + block_on(async move { chat::is_contact_in_chat(&ctx, ChatId::new(chat_id), contact_id).await }) + .into() } #[no_mangle] @@ -1414,12 +1176,11 @@ pub unsafe extern "C" fn dc_add_contact_to_chat( eprintln!("ignoring careless call to dc_add_contact_to_chat()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { chat::add_contact_to_chat(&ctx, ChatId::new(chat_id), contact_id).await as libc::c_int }) - .unwrap_or(0) } #[no_mangle] @@ -1432,15 +1193,14 @@ pub unsafe extern "C" fn dc_remove_contact_from_chat( eprintln!("ignoring careless call to dc_remove_contact_from_chat()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { chat::remove_contact_from_chat(&ctx, ChatId::new(chat_id), contact_id) .await .map(|_| 1) .unwrap_or_log_default(&ctx, "Failed to remove contact") }) - .unwrap_or(0) } #[no_mangle] @@ -1453,15 +1213,14 @@ pub unsafe extern "C" fn dc_set_chat_name( eprintln!("ignoring careless call to dc_set_chat_name()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { chat::set_chat_name(&ctx, ChatId::new(chat_id), to_string_lossy(name)) .await .map(|_| 1) .unwrap_or_log_default(&ctx, "Failed to set chat name") }) - .unwrap_or(0) } #[no_mangle] @@ -1474,15 +1233,14 @@ pub unsafe extern "C" fn dc_set_chat_profile_image( eprintln!("ignoring careless call to dc_set_chat_profile_image()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { chat::set_chat_profile_image(&ctx, ChatId::new(chat_id), to_string_lossy(image)) .await .map(|_| 1) .unwrap_or_log_default(&ctx, "Failed to set profile image") }) - .unwrap_or(0) } #[no_mangle] @@ -1495,26 +1253,26 @@ pub unsafe extern "C" fn dc_set_chat_mute_duration( eprintln!("ignoring careless call to dc_set_chat_mute_duration()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; let muteDuration = match duration { 0 => MuteDuration::NotMuted, -1 => MuteDuration::Forever, n if n > 0 => MuteDuration::Until(SystemTime::now() + Duration::from_secs(duration as u64)), _ => { - ffi_context.warning( + warn!( + ctx, "dc_chat_set_mute_duration(): Can not use negative duration other than -1", ); return 0; } }; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { chat::set_muted(&ctx, ChatId::new(chat_id), muteDuration) .await .map(|_| 1) .unwrap_or_log_default(&ctx, "Failed to set mute duration") }) - .unwrap_or(0) } #[no_mangle] @@ -1526,15 +1284,9 @@ pub unsafe extern "C" fn dc_get_msg_info( eprintln!("ignoring careless call to dc_get_msg_info()"); return "".strdup(); } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!( - ffi_context, - ctx, - message::get_msg_info(&ctx, MsgId::new(msg_id)) - ) - .map(|s| s.strdup()) - .unwrap_or_else(|_| ptr::null_mut()) + block_on(message::get_msg_info(&ctx, MsgId::new(msg_id))).strdup() } #[no_mangle] @@ -1546,15 +1298,14 @@ pub unsafe extern "C" fn dc_get_mime_headers( eprintln!("ignoring careless call to dc_get_mime_headers()"); return ptr::null_mut(); // NULL explicitly defined as "no mime headers" } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { message::get_mime_headers(&ctx, MsgId::new(msg_id)) .await .map(|s| s.strdup()) .unwrap_or_else(ptr::null_mut) }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -1567,10 +1318,10 @@ pub unsafe extern "C" fn dc_delete_msgs( eprintln!("ignoring careless call to dc_delete_msgs()"); return; } - let ffi_context = &*context; + let ctx = &*context; let msg_ids = convert_and_prune_message_ids(msg_ids, msg_cnt); - with_inner_async!(ffi_context, ctx, message::delete_msgs(&ctx, &msg_ids)).unwrap_or(()) + block_on(message::delete_msgs(&ctx, &msg_ids)) } #[no_mangle] @@ -1579,9 +1330,9 @@ pub unsafe extern "C" fn dc_empty_server(context: *mut dc_context_t, flags: u32) eprintln!("ignoring careless call to dc_empty_server()"); return; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, message::dc_empty_server(&ctx, flags)).unwrap_or(()) + block_on(message::dc_empty_server(&ctx, flags)) } #[no_mangle] @@ -1600,14 +1351,13 @@ pub unsafe extern "C" fn dc_forward_msgs( return; } let msg_ids = convert_and_prune_message_ids(msg_ids, msg_cnt); - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { chat::forward_msgs(&ctx, &msg_ids[..], ChatId::new(chat_id)) .await .unwrap_or_log_default(&ctx, "Failed to forward message") }) - .unwrap_or_default() } #[no_mangle] @@ -1616,9 +1366,9 @@ pub unsafe extern "C" fn dc_marknoticed_contact(context: *mut dc_context_t, cont eprintln!("ignoring careless call to dc_marknoticed_contact()"); return; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, Contact::mark_noticed(&ctx, contact_id)).unwrap_or(()) + block_on(Contact::mark_noticed(&ctx, contact_id)) } #[no_mangle] @@ -1632,9 +1382,9 @@ pub unsafe extern "C" fn dc_markseen_msgs( return; } let msg_ids = convert_and_prune_message_ids(msg_ids, msg_cnt); - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, message::markseen_msgs(&ctx, msg_ids)).ok(); + block_on(message::markseen_msgs(&ctx, msg_ids)); } #[no_mangle] @@ -1649,14 +1399,9 @@ pub unsafe extern "C" fn dc_star_msgs( return; } let msg_ids = convert_and_prune_message_ids(msg_ids, msg_cnt); - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!( - ffi_context, - ctx, - message::star_msgs(&ctx, msg_ids, star == 1) - ) - .ok(); + block_on(message::star_msgs(&ctx, msg_ids, star == 1)); } #[no_mangle] @@ -1665,9 +1410,9 @@ pub unsafe extern "C" fn dc_get_msg(context: *mut dc_context_t, msg_id: u32) -> eprintln!("ignoring careless call to dc_get_msg()"); return ptr::null_mut(); } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { let message = match message::Message::load_from_db(&ctx, MsgId::new(msg_id)).await { Ok(msg) => msg, Err(e) => { @@ -1690,7 +1435,6 @@ pub unsafe extern "C" fn dc_get_msg(context: *mut dc_context_t, msg_id: u32) -> let ffi_msg = MessageWrapper { context, message }; Box::into_raw(Box::new(ffi_msg)) }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -1712,14 +1456,13 @@ pub unsafe extern "C" fn dc_lookup_contact_id_by_addr( eprintln!("ignoring careless call to dc_lookup_contact_id_by_addr()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!( - ffi_context, - ctx, - Contact::lookup_id_by_addr(&ctx, to_string_lossy(addr), Origin::IncomingReplyTo) - ) - .unwrap_or(0) + block_on(Contact::lookup_id_by_addr( + &ctx, + to_string_lossy(addr), + Origin::IncomingReplyTo, + )) } #[no_mangle] @@ -1732,16 +1475,15 @@ pub unsafe extern "C" fn dc_create_contact( eprintln!("ignoring careless call to dc_create_contact()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; let name = to_string_lossy(name); - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { match Contact::create(&ctx, name, to_string_lossy(addr)).await { Ok(id) => id, Err(_) => 0, } }) - .unwrap_or(0) } #[no_mangle] @@ -1753,15 +1495,14 @@ pub unsafe extern "C" fn dc_add_address_book( eprintln!("ignoring careless call to dc_add_address_book()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { match Contact::add_address_book(&ctx, to_string_lossy(addr_book)).await { Ok(cnt) => cnt as libc::c_int, Err(_) => 0, } }) - .unwrap_or(0) } #[no_mangle] @@ -1774,16 +1515,15 @@ pub unsafe extern "C" fn dc_get_contacts( eprintln!("ignoring careless call to dc_get_contacts()"); return ptr::null_mut(); } - let ffi_context = &*context; + let ctx = &*context; let query = to_opt_string_lossy(query); - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { match Contact::get_all(&ctx, flags, query).await { Ok(contacts) => Box::into_raw(Box::new(dc_array_t::from(contacts))), Err(_) => ptr::null_mut(), } }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -1792,9 +1532,9 @@ pub unsafe extern "C" fn dc_get_blocked_cnt(context: *mut dc_context_t) -> libc: eprintln!("ignoring careless call to dc_get_blocked_cnt()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, Contact::get_blocked_cnt(&ctx)).unwrap_or(0) as libc::c_int + block_on(Contact::get_blocked_cnt(&ctx)) as libc::c_int } #[no_mangle] @@ -1805,14 +1545,13 @@ pub unsafe extern "C" fn dc_get_blocked_contacts( eprintln!("ignoring careless call to dc_get_blocked_contacts()"); return ptr::null_mut(); } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { Box::into_raw(Box::new(dc_array_t::from( Contact::get_all_blocked(&ctx).await, ))) }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -1825,15 +1564,14 @@ pub unsafe extern "C" fn dc_block_contact( eprintln!("ignoring careless call to dc_block_contact()"); return; } - let ffi_context = &*context; - with_inner_async!(ffi_context, ctx, async move { + let ctx = &*context; + block_on(async move { if block == 0 { Contact::unblock(&ctx, contact_id).await; } else { Contact::block(&ctx, contact_id).await; } - }) - .ok(); + }); } #[no_mangle] @@ -1845,9 +1583,9 @@ pub unsafe extern "C" fn dc_get_contact_encrinfo( eprintln!("ignoring careless call to dc_get_contact_encrinfo()"); return "".strdup(); } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { Contact::get_encrinfo(&ctx, contact_id) .await .map(|s| s.strdup()) @@ -1856,7 +1594,6 @@ pub unsafe extern "C" fn dc_get_contact_encrinfo( ptr::null_mut() }) }) - .unwrap_or_else(|_| "".strdup()) } #[no_mangle] @@ -1868,15 +1605,14 @@ pub unsafe extern "C" fn dc_delete_contact( eprintln!("ignoring careless call to dc_delete_contact()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { match Contact::delete(&ctx, contact_id).await { Ok(_) => 1, Err(_) => 0, } }) - .unwrap_or(0) } #[no_mangle] @@ -1888,15 +1624,14 @@ pub unsafe extern "C" fn dc_get_contact( eprintln!("ignoring careless call to dc_get_contact()"); return ptr::null_mut(); } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { Contact::get_by_id(&ctx, contact_id) .await .map(|contact| Box::into_raw(Box::new(ContactWrapper { context, contact }))) .unwrap_or_else(|_| ptr::null_mut()) }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -1918,16 +1653,15 @@ pub unsafe extern "C" fn dc_imex( } }; - let ffi_context = &*context; + let ctx = &*context; let param1 = to_opt_string_lossy(param1); - with_inner_spawn!(ffi_context, ctx, async move { + spawn(async move { imex::imex(&ctx, what, param1) .await - .log_err(ffi_context, "IMEX failed") - }) - .ok(); + .log_err(ctx, "IMEX failed") + }); } #[no_mangle] @@ -1939,9 +1673,9 @@ pub unsafe extern "C" fn dc_imex_has_backup( eprintln!("ignoring careless call to dc_imex_has_backup()"); return ptr::null_mut(); // NULL explicitly defined as "has no backup" } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { match imex::has_backup(&ctx, to_string_lossy(dir)).await { Ok(res) => res.strdup(), Err(err) => { @@ -1952,7 +1686,6 @@ pub unsafe extern "C" fn dc_imex_has_backup( } } }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -1961,9 +1694,9 @@ pub unsafe extern "C" fn dc_initiate_key_transfer(context: *mut dc_context_t) -> eprintln!("ignoring careless call to dc_initiate_key_transfer()"); return ptr::null_mut(); // NULL explicitly defined as "error" } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { match imex::initiate_key_transfer(&ctx).await { Ok(res) => res.strdup(), Err(err) => { @@ -1972,7 +1705,6 @@ pub unsafe extern "C" fn dc_initiate_key_transfer(context: *mut dc_context_t) -> } } }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -1988,9 +1720,9 @@ pub unsafe extern "C" fn dc_continue_key_transfer( eprintln!("ignoring careless call to dc_continue_key_transfer()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { match imex::continue_key_transfer(&ctx, MsgId::new(msg_id), &to_string_lossy(setup_code)) .await { @@ -2001,7 +1733,6 @@ pub unsafe extern "C" fn dc_continue_key_transfer( } } }) - .unwrap_or(0) } #[no_mangle] @@ -2010,8 +1741,8 @@ pub unsafe extern "C" fn dc_stop_ongoing_process(context: *mut dc_context_t) { eprintln!("ignoring careless call to dc_stop_ongoing_process()"); return; } - let ffi_context = &*context; - with_inner_async!(ffi_context, ctx, ctx.stop_ongoing()).ok(); + let ctx = &*context; + block_on(ctx.stop_ongoing()); } #[no_mangle] @@ -2023,13 +1754,12 @@ pub unsafe extern "C" fn dc_check_qr( eprintln!("ignoring careless call to dc_check_qr()"); return ptr::null_mut(); } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { let lot = qr::check_qr(&ctx, to_string_lossy(qr)).await; Box::into_raw(Box::new(lot)) }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -2041,15 +1771,14 @@ pub unsafe extern "C" fn dc_get_securejoin_qr( eprintln!("ignoring careless call to dc_get_securejoin_qr()"); return "".strdup(); } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { securejoin::dc_get_securejoin_qr(&ctx, ChatId::new(chat_id)) .await .unwrap_or_else(|| "".to_string()) .strdup() }) - .unwrap_or_else(|_| "".strdup()) } #[no_mangle] @@ -2061,13 +1790,10 @@ pub unsafe extern "C" fn dc_join_securejoin( eprintln!("ignoring careless call to dc_join_securejoin()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { - securejoin::dc_join_securejoin(&ctx, &to_string_lossy(qr)).await - }) - .map(|v| v.to_u32()) - .unwrap_or(0) + block_on(async move { securejoin::dc_join_securejoin(&ctx, &to_string_lossy(qr)).await }) + .to_u32() } #[no_mangle] @@ -2080,12 +1806,9 @@ pub unsafe extern "C" fn dc_send_locations_to_chat( eprintln!("ignoring careless call to dc_send_locations_to_chat()"); return; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, { - location::send_locations_to_chat(&ctx, ChatId::new(chat_id), seconds as i64) - }) - .ok(); + block_on({ location::send_locations_to_chat(&ctx, ChatId::new(chat_id), seconds as i64) }); } #[no_mangle] @@ -2097,14 +1820,12 @@ pub unsafe extern "C" fn dc_is_sending_locations_to_chat( eprintln!("ignoring careless call to dc_is_sending_locations_to_chat()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!( - ffi_context, - ctx, - location::is_sending_locations_to_chat(&ctx, ChatId::new(chat_id)) - ) - .unwrap_or_default() as libc::c_int + block_on(location::is_sending_locations_to_chat( + &ctx, + ChatId::new(chat_id), + )) as libc::c_int } #[no_mangle] @@ -2118,14 +1839,9 @@ pub unsafe extern "C" fn dc_set_location( eprintln!("ignoring careless call to dc_set_location()"); return 0; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!( - ffi_context, - ctx, - location::set(&ctx, latitude, longitude, accuracy) - ) - .unwrap_or(false) as _ + block_on(location::set(&ctx, latitude, longitude, accuracy)) as _ } #[no_mangle] @@ -2140,9 +1856,9 @@ pub unsafe extern "C" fn dc_get_locations( eprintln!("ignoring careless call to dc_get_locations()"); return ptr::null_mut(); } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { let res = location::get_range( &ctx, ChatId::new(chat_id), @@ -2153,7 +1869,6 @@ pub unsafe extern "C" fn dc_get_locations( .await; Box::into_raw(Box::new(dc_array_t::from(res))) }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -2162,14 +1877,14 @@ pub unsafe extern "C" fn dc_delete_all_locations(context: *mut dc_context_t) { eprintln!("ignoring careless call to dc_delete_all_locations()"); return; } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { location::delete_all(&ctx) .await - .log_err(ffi_context, "Failed to delete locations") - }) - .ok(); + .log_err(ctx, "Failed to delete locations") + .ok() + }); } // dc_array_t @@ -2436,16 +2151,15 @@ pub unsafe extern "C" fn dc_chatlist_get_summary( Some(&ffi_chat.chat) }; let ffi_list = &*chatlist; - let ffi_context: &ContextWrapper = &*ffi_list.context; + let ctx = &*ffi_list.context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { let lot = ffi_list .list .get_summary(&ctx, index as usize, maybe_chat) .await; Box::into_raw(Box::new(lot)) }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -2524,15 +2238,14 @@ pub unsafe extern "C" fn dc_chat_get_profile_image(chat: *mut dc_chat_t) -> *mut return ptr::null_mut(); // NULL explicitly defined as "no image" } let ffi_chat = &*chat; - let ffi_context = &*ffi_chat.context; + let ctx = &*ffi_chat.context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { match ffi_chat.chat.get_profile_image(&ctx).await { Some(p) => p.to_string_lossy().strdup(), None => ptr::null_mut(), } }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -2542,9 +2255,9 @@ pub unsafe extern "C" fn dc_chat_get_color(chat: *mut dc_chat_t) -> u32 { return 0; } let ffi_chat = &*chat; - let ffi_context = &*ffi_chat.context; + let ctx = &*ffi_chat.context; - with_inner_async!(ffi_context, ctx, ffi_chat.chat.get_color(&ctx)).unwrap_or(0) + block_on(ffi_chat.chat.get_color(&ctx)) } #[no_mangle] @@ -2661,9 +2374,9 @@ pub unsafe extern "C" fn dc_chat_get_info_json( eprintln!("ignoring careless call to dc_chat_get_info_json()"); return "".strdup(); } - let ffi_context = &*context; + let ctx = &*context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { let chat = match chat::Chat::load_from_db(&ctx, ChatId::new(chat_id)).await { Ok(chat) => chat, Err(err) => { @@ -2685,7 +2398,6 @@ pub unsafe extern "C" fn dc_chat_get_info_json( .unwrap_or_log_default(&ctx, "dc_get_chat_info_json() failed to serialise to json") .strdup() }) - .unwrap_or_else(|_| "".strdup()) } // dc_msg_t @@ -2834,16 +2546,12 @@ pub unsafe extern "C" fn dc_msg_get_file(msg: *mut dc_msg_t) -> *mut libc::c_cha return "".strdup(); } let ffi_msg = &*msg; - let ffi_context = &*ffi_msg.context; - ffi_context - .with_inner(|ctx| { - ffi_msg - .message - .get_file(ctx) - .map(|p| p.to_string_lossy().strdup()) - .unwrap_or_else(|| "".strdup()) - }) - .unwrap_or_else(|_| "".strdup()) + let ctx = &*ffi_msg.context; + ffi_msg + .message + .get_file(ctx) + .map(|p| p.to_string_lossy().strdup()) + .unwrap_or_else(|| "".strdup()) } #[no_mangle] @@ -2877,9 +2585,9 @@ pub unsafe extern "C" fn dc_msg_get_filebytes(msg: *mut dc_msg_t) -> u64 { return 0; } let ffi_msg = &*msg; - let ffi_context = &*ffi_msg.context; + let ctx = &*ffi_msg.context; - with_inner_async!(ffi_context, ctx, ffi_msg.message.get_filebytes(&ctx)).unwrap_or(0) + block_on(ffi_msg.message.get_filebytes(&ctx)) } #[no_mangle] @@ -2938,13 +2646,12 @@ pub unsafe extern "C" fn dc_msg_get_summary( Some(&ffi_chat.chat) }; let ffi_msg = &mut *msg; - let ffi_context = &*ffi_msg.context; + let ctx = &*ffi_msg.context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { let lot = ffi_msg.message.get_summary(&ctx, maybe_chat).await; Box::into_raw(Box::new(lot)) }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -2957,14 +2664,13 @@ pub unsafe extern "C" fn dc_msg_get_summarytext( return "".strdup(); } let ffi_msg = &mut *msg; - let ffi_context = &*ffi_msg.context; + let ctx = &*ffi_msg.context; - with_inner_async!(ffi_context, ctx, { + block_on({ ffi_msg .message .get_summarytext(&ctx, approx_characters.try_into().unwrap_or_default()) }) - .unwrap_or_default() .strdup() } @@ -3055,10 +2761,9 @@ pub unsafe extern "C" fn dc_msg_get_setupcodebegin(msg: *mut dc_msg_t) -> *mut l return "".strdup(); } let ffi_msg = &*msg; - let ffi_context = &*ffi_msg.context; + let ctx = &*ffi_msg.context; - with_inner_async!(ffi_context, ctx, ffi_msg.message.get_setupcodebegin(&ctx)) - .map(|s| s.unwrap_or_default()) + block_on(ffi_msg.message.get_setupcodebegin(&ctx)) .unwrap_or_default() .strdup() } @@ -3140,14 +2845,13 @@ pub unsafe extern "C" fn dc_msg_latefiling_mediasize( return; } let ffi_msg = &mut *msg; - let ffi_context = &*ffi_msg.context; + let ctx = &*ffi_msg.context; - with_inner_async!(ffi_context, ctx, { + block_on({ ffi_msg .message .latefiling_mediasize(&ctx, width, height, duration) - }) - .ok(); + }); } // dc_contact_t @@ -3251,9 +2955,9 @@ pub unsafe extern "C" fn dc_contact_get_profile_image( return ptr::null_mut(); // NULL explicitly defined as "no profile image" } let ffi_contact = &*contact; - let ffi_context = &*ffi_contact.context; + let ctx = &*ffi_contact.context; - with_inner_async!(ffi_context, ctx, async move { + block_on(async move { ffi_contact .contact .get_profile_image(&ctx) @@ -3261,7 +2965,6 @@ pub unsafe extern "C" fn dc_contact_get_profile_image( .map(|p| p.to_string_lossy().strdup()) .unwrap_or_else(std::ptr::null_mut) }) - .unwrap_or_else(|_| ptr::null_mut()) } #[no_mangle] @@ -3291,12 +2994,9 @@ pub unsafe extern "C" fn dc_contact_is_verified(contact: *mut dc_contact_t) -> l return 0; } let ffi_contact = &*contact; - let ffi_context = &*ffi_contact.context; + let ctx = &*ffi_contact.context; - with_inner_async!(ffi_context, ctx, async move { - ffi_contact.contact.is_verified(&ctx).await as libc::c_int - }) - .unwrap_or(0) + block_on(async move { ffi_contact.contact.is_verified(&ctx).await as libc::c_int }) } // dc_lot_t @@ -3394,7 +3094,7 @@ trait ResultExt { /// /// You can do this as soon as the wrapper exists, it does not /// have to be open (which is required for the `warn!()` macro). - fn log_err(self, wrapper: &ContextWrapper, message: &str) -> Result; + fn log_err(self, wrapper: &Context, message: &str) -> Result; } impl ResultExt for Result { @@ -3408,11 +3108,9 @@ impl ResultExt for Result { } } - fn log_err(self, wrapper: &ContextWrapper, message: &str) -> Result { + fn log_err(self, ctx: &Context, message: &str) -> Result { self.map_err(|err| { - unsafe { - wrapper.warning(&format!("{}: {}", message, err)); - } + warn!(ctx, "{}: {}", message, err); err }) }