config.rs (2677B)
1 use crate::bindings; 2 3 #[derive(Copy, Clone)] 4 pub struct Config { 5 pub config: bindings::ndb_config, 6 // We add a flag to know if we've installed a Rust closure so we can clean it up in Drop. 7 is_rust_closure: bool, 8 } 9 10 impl Default for Config { 11 fn default() -> Self { 12 Config::new() 13 } 14 } 15 16 impl Config { 17 pub fn new() -> Self { 18 let mut config = bindings::ndb_config { 19 filter_context: std::ptr::null_mut(), 20 sub_cb: None, 21 sub_cb_ctx: std::ptr::null_mut(), 22 ingest_filter: None, 23 flags: 0, 24 ingester_threads: 0, 25 mapsize: 0, 26 }; 27 28 unsafe { 29 bindings::ndb_default_config(&mut config); 30 } 31 32 let is_rust_closure = false; 33 Config { 34 config, 35 is_rust_closure, 36 } 37 } 38 39 // 40 pub fn set_flags(mut self, flags: i32) -> Self { 41 self.config.flags = flags; 42 self 43 } 44 45 pub fn skip_validation(mut self, skip: bool) -> Self { 46 let skip_note_verify: i32 = 1 << 1; 47 48 if skip { 49 self.config.flags |= skip_note_verify; 50 } else { 51 self.config.flags &= !skip_note_verify; 52 } 53 54 self 55 } 56 57 /// Set a callback for when we have 58 pub fn set_sub_callback<F>(mut self, closure: F) -> Self 59 where 60 F: FnMut(u64) + 'static, 61 { 62 // Box the closure to ensure it has a stable address. 63 let boxed_closure: Box<dyn FnMut(u64)> = Box::new(closure); 64 65 // Convert it to a raw pointer to store in sub_cb_ctx. 66 let ctx_ptr = Box::into_raw(Box::new(boxed_closure)) as *mut ::std::os::raw::c_void; 67 68 self.config.sub_cb = Some(sub_callback_trampoline); 69 self.config.sub_cb_ctx = ctx_ptr; 70 self.is_rust_closure = true; 71 self 72 } 73 74 pub fn set_mapsize(mut self, bytes: usize) -> Self { 75 self.config.mapsize = bytes; 76 self 77 } 78 79 pub fn set_ingester_threads(mut self, threads: i32) -> Self { 80 self.config.ingester_threads = threads; 81 self 82 } 83 84 // Internal method to get a raw pointer to the config, used in Ndb 85 pub fn as_ptr(&self) -> *const bindings::ndb_config { 86 &self.config 87 } 88 } 89 90 extern "C" fn sub_callback_trampoline(ctx: *mut ::std::os::raw::c_void, subid: u64) { 91 unsafe { 92 // Convert the raw pointer back into a reference to our closure. 93 // We know this pointer was created by Box::into_raw in `set_sub_callback_rust`. 94 let closure_ptr = ctx as *mut Box<dyn FnMut(u64)>; 95 assert!(!closure_ptr.is_null()); 96 let closure = &mut *closure_ptr; 97 closure(subid); 98 } 99 }