mirror of
https://github.com/logos-messaging/logos-delivery-rust-bindings.git
synced 2026-03-08 01:43:08 +00:00
74 lines
2.1 KiB
Rust
74 lines
2.1 KiB
Rust
use crate::general::libwaku_response::LibwakuResponse;
|
|
|
|
use std::{slice, str};
|
|
use waku_sys::WakuCallBack;
|
|
|
|
unsafe extern "C" fn trampoline<F>(
|
|
ret_code: ::std::os::raw::c_int,
|
|
data: *const ::std::os::raw::c_char,
|
|
data_len: usize,
|
|
user_data: *mut ::std::os::raw::c_void,
|
|
) where
|
|
F: FnMut(LibwakuResponse),
|
|
{
|
|
let closure = &mut *(user_data as *mut F);
|
|
|
|
let response = if data.is_null() {
|
|
""
|
|
} else {
|
|
str::from_utf8(slice::from_raw_parts(data as *mut u8, data_len))
|
|
.expect("could not retrieve response")
|
|
};
|
|
|
|
let result = LibwakuResponse::try_from((ret_code as u32, response))
|
|
.expect("invalid response obtained from libwaku");
|
|
|
|
closure(result);
|
|
}
|
|
|
|
pub fn get_trampoline<F>(_closure: &F) -> WakuCallBack
|
|
where
|
|
F: FnMut(LibwakuResponse),
|
|
{
|
|
Some(trampoline::<F>)
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! handle_ffi_call {
|
|
// Case: With or without additional arguments
|
|
($waku_fn:expr, $resp_hndlr:expr, $ctx:expr $(, $($arg:expr),*)?) => {{
|
|
use $crate::macros::get_trampoline;
|
|
use std::sync::Arc;
|
|
use tokio::sync::Notify;
|
|
use libc::*;
|
|
|
|
let mut result = LibwakuResponse::default();
|
|
let notify = Arc::new(Notify::new());
|
|
let notify_clone = notify.clone();
|
|
|
|
// Callback to update the result and notify the waiter
|
|
let result_cb = |r: LibwakuResponse| {
|
|
result = r;
|
|
notify_clone.notify_one();
|
|
};
|
|
|
|
let mut closure = result_cb;
|
|
// Create trampoline and invoke the `waku_sys` function
|
|
let code = unsafe {
|
|
let cb = get_trampoline(&closure);
|
|
$waku_fn(
|
|
$ctx, // Pass the context
|
|
$($($arg),*,)? // Expand the variadic arguments if provided
|
|
cb, // Pass the callback trampoline
|
|
&mut closure as *mut _ as *mut c_void
|
|
)
|
|
};
|
|
|
|
// Wait for the callback to notify us
|
|
notify.notified().await;
|
|
|
|
// Handle the response
|
|
$resp_hndlr(code, result)
|
|
}};
|
|
}
|