diff --git a/src/collation.rs b/src/collation.rs index ade51e0..c467c62 100644 --- a/src/collation.rs +++ b/src/collation.rs @@ -1,7 +1,7 @@ //! Add, remove, or modify a collation use std::cmp::Ordering; use std::os::raw::{c_char, c_int, c_void}; -use std::panic::{catch_unwind, UnwindSafe}; +use std::panic::catch_unwind; use std::ptr; use std::slice; @@ -18,7 +18,7 @@ impl Connection { #[inline] pub fn create_collation(&self, collation_name: &str, x_compare: C) -> Result<()> where - C: Fn(&str, &str) -> Ordering + Send + UnwindSafe + 'static, + C: Fn(&str, &str) -> Ordering + Send + 'static, { self.db .borrow_mut() @@ -44,7 +44,7 @@ impl Connection { impl InnerConnection { fn create_collation(&mut self, collation_name: &str, x_compare: C) -> Result<()> where - C: Fn(&str, &str) -> Ordering + Send + UnwindSafe + 'static, + C: Fn(&str, &str) -> Ordering + Send + 'static, { unsafe extern "C" fn call_boxed_closure( arg1: *mut c_void, diff --git a/src/functions.rs b/src/functions.rs index f4a508c..7a00152 100644 --- a/src/functions.rs +++ b/src/functions.rs @@ -444,7 +444,7 @@ impl Connection { x_func: F, ) -> Result<()> where - F: FnMut(&Context<'_>) -> Result + Send + UnwindSafe + 'static, + F: FnMut(&Context<'_>) -> Result + Send + 'static, T: SqlFnOutput, { self.db @@ -526,7 +526,7 @@ impl InnerConnection { x_func: F, ) -> Result<()> where - F: FnMut(&Context<'_>) -> Result + Send + UnwindSafe + 'static, + F: FnMut(&Context<'_>) -> Result + Send + 'static, T: SqlFnOutput, { unsafe extern "C" fn call_boxed_closure( diff --git a/src/hooks.rs b/src/hooks.rs index 108334b..652d474 100644 --- a/src/hooks.rs +++ b/src/hooks.rs @@ -2,7 +2,7 @@ #![allow(non_camel_case_types)] use std::os::raw::{c_char, c_int, c_void}; -use std::panic::{catch_unwind, RefUnwindSafe}; +use std::panic::catch_unwind; use std::ptr; use crate::ffi; @@ -388,7 +388,7 @@ impl Connection { /// If the progress callback returns `true`, the operation is interrupted. pub fn progress_handler(&self, num_ops: c_int, handler: Option) where - F: FnMut() -> bool + Send + RefUnwindSafe + 'static, + F: FnMut() -> bool + Send + 'static, { self.db.borrow_mut().progress_handler(num_ops, handler); } @@ -398,7 +398,7 @@ impl Connection { #[inline] pub fn authorizer<'c, F>(&self, hook: Option) where - F: for<'r> FnMut(AuthContext<'r>) -> Authorization + Send + RefUnwindSafe + 'static, + F: for<'r> FnMut(AuthContext<'r>) -> Authorization + Send + 'static, { self.db.borrow_mut().authorizer(hook); } @@ -554,7 +554,7 @@ impl InnerConnection { fn progress_handler(&mut self, num_ops: c_int, handler: Option) where - F: FnMut() -> bool + Send + RefUnwindSafe + 'static, + F: FnMut() -> bool + Send + 'static, { unsafe extern "C" fn call_boxed_closure(p_arg: *mut c_void) -> c_int where @@ -586,7 +586,7 @@ impl InnerConnection { fn authorizer<'c, F>(&'c mut self, authorizer: Option) where - F: for<'r> FnMut(AuthContext<'r>) -> Authorization + Send + RefUnwindSafe + 'static, + F: for<'r> FnMut(AuthContext<'r>) -> Authorization + Send + 'static, { unsafe extern "C" fn call_boxed_closure<'c, F>( p_arg: *mut c_void, diff --git a/src/session.rs b/src/session.rs index c5c785d..a39de09 100644 --- a/src/session.rs +++ b/src/session.rs @@ -5,7 +5,7 @@ use std::ffi::CStr; use std::io::{Read, Write}; use std::marker::PhantomData; use std::os::raw::{c_char, c_int, c_uchar, c_void}; -use std::panic::{catch_unwind, RefUnwindSafe}; +use std::panic::catch_unwind; use std::ptr; use std::slice::{from_raw_parts, from_raw_parts_mut}; @@ -59,20 +59,22 @@ impl Session<'_> { /// Set a table filter pub fn table_filter(&mut self, filter: Option) where - F: Fn(&str) -> bool + Send + RefUnwindSafe + 'static, + F: Fn(&str) -> bool + Send + 'static, { unsafe extern "C" fn call_boxed_closure( p_arg: *mut c_void, tbl_str: *const c_char, ) -> c_int where - F: Fn(&str) -> bool + RefUnwindSafe, + F: Fn(&str) -> bool, { - let boxed_filter: *mut F = p_arg as *mut F; let tbl_name = CStr::from_ptr(tbl_str).to_str(); c_int::from( - catch_unwind(|| (*boxed_filter)(tbl_name.expect("non-utf8 table name"))) - .unwrap_or_default(), + catch_unwind(|| { + let boxed_filter: *mut F = p_arg.cast::(); + (*boxed_filter)(tbl_name.expect("non-utf8 table name")) + }) + .unwrap_or_default(), ) } @@ -588,8 +590,8 @@ impl Connection { /// Apply a changeset to a database pub fn apply(&self, cs: &Changeset, filter: Option, conflict: C) -> Result<()> where - F: Fn(&str) -> bool + Send + RefUnwindSafe + 'static, - C: Fn(ConflictType, ChangesetItem) -> ConflictAction + Send + RefUnwindSafe + 'static, + F: Fn(&str) -> bool + Send + 'static, + C: Fn(ConflictType, ChangesetItem) -> ConflictAction + Send + 'static, { let db = self.db.borrow_mut().db; @@ -626,8 +628,8 @@ impl Connection { conflict: C, ) -> Result<()> where - F: Fn(&str) -> bool + Send + RefUnwindSafe + 'static, - C: Fn(ConflictType, ChangesetItem) -> ConflictAction + Send + RefUnwindSafe + 'static, + F: Fn(&str) -> bool + Send + 'static, + C: Fn(ConflictType, ChangesetItem) -> ConflictAction + Send + 'static, { let input_ref = &input; let db = self.db.borrow_mut().db; @@ -701,17 +703,21 @@ pub enum ConflictAction { unsafe extern "C" fn call_filter(p_ctx: *mut c_void, tbl_str: *const c_char) -> c_int where - F: Fn(&str) -> bool + Send + RefUnwindSafe + 'static, - C: Fn(ConflictType, ChangesetItem) -> ConflictAction + Send + RefUnwindSafe + 'static, + F: Fn(&str) -> bool + Send + 'static, + C: Fn(ConflictType, ChangesetItem) -> ConflictAction + Send + 'static, { - let tuple: *mut (Option, C) = p_ctx as *mut (Option, C); let tbl_name = CStr::from_ptr(tbl_str).to_str(); - match *tuple { - (Some(ref filter), _) => c_int::from( - catch_unwind(|| filter(tbl_name.expect("illegal table name"))).unwrap_or_default(), - ), - _ => unimplemented!(), - } + c_int::from( + catch_unwind(|| { + let tuple: *mut (Option, C) = p_ctx.cast::<(Option, C)>(); + if let Some(ref filter) = (*tuple).0 { + filter(tbl_name.expect("illegal table name")) + } else { + true + } + }) + .unwrap_or_default(), + ) } unsafe extern "C" fn call_conflict( @@ -720,13 +726,15 @@ unsafe extern "C" fn call_conflict( p: *mut ffi::sqlite3_changeset_iter, ) -> c_int where - F: Fn(&str) -> bool + Send + RefUnwindSafe + 'static, - C: Fn(ConflictType, ChangesetItem) -> ConflictAction + Send + RefUnwindSafe + 'static, + F: Fn(&str) -> bool + Send + 'static, + C: Fn(ConflictType, ChangesetItem) -> ConflictAction + Send + 'static, { - let tuple: *mut (Option, C) = p_ctx as *mut (Option, C); let conflict_type = ConflictType::from(e_conflict); let item = ChangesetItem { it: p }; - if let Ok(action) = catch_unwind(|| (*tuple).1(conflict_type, item)) { + if let Ok(action) = catch_unwind(|| { + let tuple: *mut (Option, C) = p_ctx.cast::<(Option, C)>(); + (*tuple).1(conflict_type, item) + }) { action as c_int } else { ffi::SQLITE_CHANGESET_ABORT