From 7f701260bebd7f371ee6ba66216f931f8f40a6d3 Mon Sep 17 00:00:00 2001 From: Rubens Brandao Date: Wed, 19 Jun 2024 09:57:52 -0300 Subject: [PATCH] allow Create/Open database with progress to use FnMut --- rust/src/filemetadata.rs | 83 +++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 31 deletions(-) diff --git a/rust/src/filemetadata.rs b/rust/src/filemetadata.rs index 0ef427c4e..d4152dfa3 100644 --- a/rust/src/filemetadata.rs +++ b/rust/src/filemetadata.rs @@ -205,28 +205,35 @@ impl FileMetadata { } } - pub fn create_database( - &self, - filename: S, - progress_func: Option bool>, - ) -> bool { + pub fn create_database(&self, filename: S) -> bool { let filename = filename.into_bytes_with_nul(); let filename_ptr = filename.as_ref().as_ptr() as *mut _; let raw = "Raw".into_bytes_with_nul(); let raw_ptr = raw.as_ptr() as *mut _; let handle = unsafe { BNGetFileViewOfType(self.handle, raw_ptr) }; - match progress_func { - None => unsafe { BNCreateDatabase(handle, filename_ptr, ptr::null_mut()) }, - Some(func) => unsafe { - BNCreateDatabaseWithProgress( - handle, - filename_ptr, - func as *mut libc::c_void, - Some(cb_progress_func), - ptr::null_mut(), - ) - }, + unsafe { BNCreateDatabase(handle, filename_ptr, ptr::null_mut()) } + } + + pub fn create_database_with_progress(&self, filename: S, mut progress_func: F) -> bool + where + S: BnStrCompatible, + F: FnMut(usize, usize) -> bool, + { + let filename = filename.into_bytes_with_nul(); + let filename_ptr = filename.as_ref().as_ptr() as *mut _; + let raw = "Raw".into_bytes_with_nul(); + let raw_ptr = raw.as_ptr() as *mut _; + + let handle = unsafe { BNGetFileViewOfType(self.handle, raw_ptr) }; + unsafe { + BNCreateDatabaseWithProgress( + handle, + filename_ptr, + &mut progress_func as *mut F as *mut libc::c_void, + Some(cb_progress_func::), + ptr::null_mut(), + ) } } @@ -257,24 +264,38 @@ impl FileMetadata { } } - pub fn open_database( + pub fn open_database(&self, filename: S) -> Result, ()> { + let filename = filename.into_bytes_with_nul(); + let filename_ptr = filename.as_ref().as_ptr() as *mut _; + + let view = unsafe { BNOpenExistingDatabase(self.handle, filename_ptr) }; + + if view.is_null() { + Err(()) + } else { + Ok(unsafe { BinaryView::from_raw(view) }) + } + } + + pub fn open_database_with_progress( &self, filename: S, - progress_func: Option bool>, - ) -> Result, ()> { + mut progress_func: F, + ) -> Result, ()> + where + S: BnStrCompatible, + F: FnMut(usize, usize) -> bool, + { let filename = filename.into_bytes_with_nul(); let filename_ptr = filename.as_ref().as_ptr() as *mut _; - let view = match progress_func { - None => unsafe { BNOpenExistingDatabase(self.handle, filename_ptr) }, - Some(func) => unsafe { - BNOpenExistingDatabaseWithProgress( - self.handle, - filename_ptr, - func as *mut libc::c_void, - Some(cb_progress_func), - ) - }, + let view = unsafe { + BNOpenExistingDatabaseWithProgress( + self.handle, + filename_ptr, + &mut progress_func as *mut F as *mut libc::c_void, + Some(cb_progress_func::), + ) }; if view.is_null() { @@ -305,11 +326,11 @@ unsafe impl RefCountable for FileMetadata { } } -unsafe extern "C" fn cb_progress_func( +unsafe extern "C" fn cb_progress_func bool>( ctxt: *mut ::std::os::raw::c_void, progress: usize, total: usize, ) -> bool { - let func: fn(usize, usize) -> bool = core::mem::transmute(ctxt); + let func: &mut F = &mut *(ctxt as *mut F); func(progress, total) }