Skip to main content

weaveffi_abi/
macros.rs

1//! Macros that user cdylibs invoke to expose the fixed WeaveFFI C ABI
2//! runtime surface from a single line of Rust.
3//!
4//! Every Rust cdylib that hosts generated WeaveFFI bindings must expose
5//! a small set of `#[no_mangle] extern "C"` functions that the language
6//! wrappers call into: string/byte deallocation, error clearing, and
7//! the cancel-token lifecycle. The wrappers themselves live in
8//! `weaveffi-abi` as ordinary `pub fn`s; the `extern "C"` thunks must
9//! be emitted in the *consumer's* crate because `#[no_mangle]` symbols
10//! in a transitive `rlib` are not guaranteed to be re-exported from a
11//! cdylib.
12//!
13//! Use [`export_runtime!`] once in your cdylib's `lib.rs` to wire all
14//! of them up.
15
16/// Emit `#[no_mangle] extern "C"` thunks for every runtime symbol that
17/// the WeaveFFI generators expect to find in the consuming cdylib.
18///
19/// The macro expands to a fixed set of functions named with the
20/// `weaveffi_` prefix:
21///
22/// - `weaveffi_free_string`
23/// - `weaveffi_free_bytes`
24/// - `weaveffi_error_clear`
25/// - `weaveffi_cancel_token_create`
26/// - `weaveffi_cancel_token_cancel`
27/// - `weaveffi_cancel_token_is_cancelled`
28/// - `weaveffi_cancel_token_destroy`
29///
30/// # Example
31///
32/// ```ignore
33/// // Inside a cdylib's src/lib.rs
34/// use weaveffi_abi as abi;
35///
36/// abi::export_runtime!();
37///
38/// // ... your generated/hand-written #[no_mangle] business functions ...
39/// ```
40///
41/// Invoke this macro at module scope **exactly once** in your cdylib.
42/// Multiple invocations would produce duplicate symbol definitions.
43#[macro_export]
44macro_rules! export_runtime {
45    () => {
46        #[no_mangle]
47        pub extern "C" fn weaveffi_free_string(ptr: *const ::std::os::raw::c_char) {
48            $crate::free_string(ptr)
49        }
50
51        #[no_mangle]
52        pub extern "C" fn weaveffi_free_bytes(ptr: *mut u8, len: usize) {
53            $crate::free_bytes(ptr, len)
54        }
55
56        #[no_mangle]
57        pub extern "C" fn weaveffi_error_clear(err: *mut $crate::weaveffi_error) {
58            $crate::error_clear(err)
59        }
60
61        #[no_mangle]
62        pub extern "C" fn weaveffi_cancel_token_create() -> *mut $crate::weaveffi_cancel_token {
63            $crate::cancel_token_create()
64        }
65
66        #[no_mangle]
67        pub extern "C" fn weaveffi_cancel_token_cancel(token: *mut $crate::weaveffi_cancel_token) {
68            $crate::cancel_token_cancel(token)
69        }
70
71        #[no_mangle]
72        pub extern "C" fn weaveffi_cancel_token_is_cancelled(
73            token: *const $crate::weaveffi_cancel_token,
74        ) -> bool {
75            $crate::cancel_token_is_cancelled(token)
76        }
77
78        #[no_mangle]
79        pub extern "C" fn weaveffi_cancel_token_destroy(token: *mut $crate::weaveffi_cancel_token) {
80            $crate::cancel_token_destroy(token)
81        }
82    };
83}