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}