buffi_macro/
lib.rs

1mod proc_macro;
2use ::proc_macro::TokenStream;
3
4const FUNCTION_PREFIX: &str = "buffi";
5
6/// This macro generates a compatible c function for each function in the current impl block
7///
8/// The generated c function accepts arguments as bincode serialized byte buffers and returns
9/// a bincode serialized byte buffer as well. The generated function handles (de)serialization of
10/// those buffers internally and converts the arguments/results of each function internally. In
11/// addition the generated function contains code to handle panics before reaching the FFI boundary,
12/// blocking async funtcions and converting `color_eyre::Report` error types to a FFI compatible version
13///
14/// The generated c function will be named `buffi_{function_name}`. It accepts a pointer to the current
15/// type (`Self`) as first argument. For each other argument of the rust function, two arguments for
16/// the c function are generated: `{argument}` as `*const u8` pointing to the serialized argument
17/// and `{argument}_size` as `usize` containing a buffer size. In addition a `out_ptr: *mut *mut u8`
18/// argument is generated. This pointer will be set to the output buffer allocation. The generated function
19/// returns a `usize` indicating the size of the allocated buffer. This buffer needs to be freed
20/// via `buffi_free_byte_buffer`
21///
22/// In addition this macro prepends a `#[tracing::instrument]` attribute to each function
23/// in the current impl block
24///
25/// Modules containing a `#[buffi_macro::exported]` call needs to be public!
26#[proc_macro_attribute]
27pub fn exported(_att: TokenStream, item: TokenStream) -> TokenStream {
28    match syn::parse(item.clone()).and_then(|parsed_item| proc_macro::expand(parsed_item, None)) {
29        Ok(tokenstream) => tokenstream,
30        Err(e) => {
31            let mut out = proc_macro2::TokenStream::from(item);
32            out.extend(e.to_compile_error());
33            out
34        }
35    }
36    .into()
37}