dora_operator_api_macros/
lib.rs

1use proc_macro::TokenStream;
2use proc_macro2::TokenStream as TokenStream2;
3use quote::quote;
4
5extern crate proc_macro;
6
7#[proc_macro]
8pub fn register_operator(item: TokenStream) -> TokenStream {
9    // convert from `TokenStream` to `TokenStream2`, which is used by the
10    // `syn` crate
11    let item = TokenStream2::from(item);
12    // generate the dora wrapper functions
13    let generated = register_operator_impl(&item).unwrap_or_else(|err| err.to_compile_error());
14    // output the generated functions
15    let tokens = quote! {
16        #generated
17    };
18    // convert the type back from `TokenStream2` to `TokenStream`
19    tokens.into()
20}
21
22/// Generates the wrapper functions for the annotated function.
23fn register_operator_impl(item: &TokenStream2) -> syn::Result<TokenStream2> {
24    // parse the type given to the `register_operator` macro
25    let operator_ty: syn::TypePath = syn::parse2(item.clone())
26        .map_err(|e| syn::Error::new(e.span(), "expected type as argument"))?;
27
28    let init = quote! {
29        #[unsafe(no_mangle)]
30        pub unsafe extern "C" fn dora_init_operator() -> dora_operator_api::types::DoraInitResult {
31            dora_operator_api::raw::dora_init_operator::<#operator_ty>()
32        }
33
34        const _DORA_INIT_OPERATOR: dora_operator_api::types::DoraInitOperator = dora_operator_api::types::DoraInitOperator {
35            init_operator: dora_init_operator,
36        };
37    };
38
39    let drop = quote! {
40        #[unsafe(no_mangle)]
41        pub unsafe extern "C" fn dora_drop_operator(operator_context: *mut std::ffi::c_void)
42            -> dora_operator_api::types::DoraResult
43        {
44            dora_operator_api::raw::dora_drop_operator::<#operator_ty>(operator_context)
45        }
46
47        const _DORA_DROP_OPERATOR: dora_operator_api::types::DoraDropOperator = dora_operator_api::types::DoraDropOperator {
48            drop_operator: dora_drop_operator,
49        };
50    };
51
52    let on_event = quote! {
53        #[unsafe(no_mangle)]
54        pub unsafe extern "C" fn dora_on_event(
55            event: &mut dora_operator_api::types::RawEvent,
56            send_output: &dora_operator_api::types::SendOutput,
57            operator_context: *mut std::ffi::c_void,
58        ) -> dora_operator_api::types::OnEventResult {
59            dora_operator_api::raw::dora_on_event::<#operator_ty>(
60                event, send_output, operator_context
61            )
62        }
63
64        const _DORA_ON_EVENT: dora_operator_api::types::DoraOnEvent = dora_operator_api::types::DoraOnEvent {
65            on_event: dora_operator_api::types::OnEventFn(dora_on_event),
66        };
67    };
68
69    Ok(quote! {
70        #init
71        #drop
72        #on_event
73    })
74}