wolfram_export_macros/
lib.rs1mod export;
11
12use proc_macro::TokenStream;
13use proc_macro2::TokenStream as TokenStream2;
14
15use quote::quote;
16use syn::{spanned::Spanned, Error, Item};
17
18#[proc_macro_attribute]
28pub fn init(attr: TokenStream, item: TokenStream) -> TokenStream {
29 match init_(attr.into(), item) {
30 Ok(tokens) => tokens.into(),
31 Err(err) => err.into_compile_error().into(),
32 }
33}
34
35fn init_(attr: TokenStream2, item: TokenStream) -> Result<TokenStream2, Error> {
36 if !attr.is_empty() {
37 return Err(Error::new(attr.span(), "unexpected attribute arguments"));
38 }
39
40 let item: Item = syn::parse(item)?;
41 let func = match item {
42 Item::Fn(func) => func,
43 _ => {
44 return Err(Error::new(
45 attr.span(),
46 "this attribute can only be applied to `fn(..) {..}` items",
47 ))
48 },
49 };
50
51 if let Some(async_) = func.sig.asyncness {
52 return Err(Error::new(
53 async_.span(),
54 "initialization function cannot be `async`",
55 ));
56 }
57 if let Some(lt) = func.sig.generics.lt_token {
58 return Err(Error::new(
59 lt.span(),
60 "initialization function cannot be generic",
61 ));
62 }
63 if !func.sig.inputs.is_empty() {
64 return Err(Error::new(
65 func.sig.inputs.span(),
66 "initialization function should have zero parameters",
67 ));
68 }
69
70 let user_init_fn_name: syn::Ident = func.sig.ident.clone();
71 let p = &self::export::Prefix::resolve().crate_path;
72
73 Ok(quote! {
74 #func
75
76 #[no_mangle]
77 pub unsafe extern "C" fn WolframLibrary_initialize(
78 lib: #p::sys::WolframLibraryData,
79 ) -> ::std::os::raw::c_int {
80 #p::macro_utils::init_with_user_function(
81 lib,
82 #user_init_fn_name
83 )
84 }
85 })
86}
87
88#[proc_macro_attribute]
97pub fn export(attrs: TokenStream, item: TokenStream) -> TokenStream {
98 let attrs: syn::AttributeArgs = syn::parse_macro_input!(attrs);
99 let mode = self::export::detect_mode_from_args(&attrs);
100 let attrs = self::export::strip_wstp_arg(attrs);
101 match self::export::export(mode, attrs, item) {
102 Ok(tokens) => tokens.into(),
103 Err(err) => err.into_compile_error().into(),
104 }
105}
106
107#[proc_macro_attribute]
114pub fn export_native(attrs: TokenStream, item: TokenStream) -> TokenStream {
115 let attrs: syn::AttributeArgs = syn::parse_macro_input!(attrs);
116 match self::export::export(self::export::Mode::Native, attrs, item) {
117 Ok(tokens) => tokens.into(),
118 Err(err) => err.into_compile_error().into(),
119 }
120}
121
122#[proc_macro_attribute]
129pub fn export_wstp(attrs: TokenStream, item: TokenStream) -> TokenStream {
130 let attrs: syn::AttributeArgs = syn::parse_macro_input!(attrs);
131 match self::export::export(self::export::Mode::Wstp, attrs, item) {
132 Ok(tokens) => tokens.into(),
133 Err(err) => err.into_compile_error().into(),
134 }
135}
136
137#[proc_macro_attribute]
147pub fn export_wxf(attrs: TokenStream, item: TokenStream) -> TokenStream {
148 let attrs: syn::AttributeArgs = syn::parse_macro_input!(attrs);
149 match self::export::export(self::export::Mode::Wxf, attrs, item) {
150 Ok(tokens) => tokens.into(),
151 Err(err) => err.into_compile_error().into(),
152 }
153}