Skip to content

Commit aa27f5e

Browse files
committed
chore(ffi): allow async fns in ffi_fn macro
This wraps the inner asynchronous function with a `::futures::executor::block_on`, allowing for asynchronous function to be more easily called by the FFI. Signed-off-by: JP-Ellis <josh@jpellis.me>
1 parent 9f74b80 commit aa27f5e

1 file changed

Lines changed: 27 additions & 0 deletions

File tree

rust/pact_ffi/src/util/ffi.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,31 @@ macro_rules! ffi_fn {
3131
($(#[$doc:meta])* fn $name:ident($($arg:ident: $arg_ty:ty),*) $body:block ) => {
3232
$crate::ffi_fn!($(#[$doc])* fn $name($($arg: $arg_ty),*) -> () $body {});
3333
};
34+
35+
// Support async functions as well, by wrapping them in a block_on call
36+
($(#[$doc:meta])* async fn $name:ident($($arg:ident: $arg_ty:ty),*) -> $ret:ty $body:block $fail:block ) => {
37+
$(#[$doc])*
38+
#[no_mangle]
39+
#[allow(clippy::or_fun_call)]
40+
#[allow(clippy::not_unsafe_ptr_arg_deref)]
41+
pub extern fn $name($($arg: $arg_ty),*) -> $ret {
42+
use $crate::error::catch_panic;
43+
44+
::tracing::debug!("{}::{} FFI function invoked", module_path!(), stringify!($name));
45+
46+
$(
47+
::tracing::trace!("@param {} = {:?}", stringify!($arg), $arg);
48+
)*
49+
50+
let output = catch_panic(|| ::futures::executor::block_on(async { Ok($body) })).unwrap_or($fail);
51+
52+
::tracing::trace!(output = ?output, "{} FFI function completed", stringify!($name));
53+
54+
output
55+
}
56+
};
57+
58+
($(#[$doc:meta])* async fn $name:ident($($arg:ident: $arg_ty:ty),*) $body:block ) => {
59+
$crate::ffi_fn!($(#[$doc])* async fn $name($($arg: $arg_ty),*) -> () $body {});
60+
};
3461
}

0 commit comments

Comments
 (0)