ocaml_interop_derive/
lib.rs

1use proc_macro::TokenStream;
2use syn::ItemFn;
3
4mod core;
5mod expansion;
6mod parsing;
7mod validation;
8
9fn export_internal_logic(
10    attr_ts: proc_macro2::TokenStream,
11    item_ts: proc_macro2::TokenStream,
12) -> Result<proc_macro2::TokenStream, syn::Error> {
13    let input_fn = syn::parse2::<ItemFn>(item_ts.clone()).map_err(|e| {
14        syn::Error::new(
15            e.span(),
16            format!("Failed to parse input item as a function: {e}. Input was: {item_ts}",),
17        )
18    })?;
19
20    let parsed_data = parsing::parse_export_definition(attr_ts, &input_fn)?;
21
22    validation::validate_parsed_data(&parsed_data)?;
23
24    expansion::expand_function_from_data(&parsed_data)
25}
26
27// --- Proc Macro Entry Point ---
28#[proc_macro_attribute]
29pub fn export(attr: TokenStream, item: TokenStream) -> TokenStream {
30    let attr_ts2 = proc_macro2::TokenStream::from(attr);
31    let item_ts2 = proc_macro2::TokenStream::from(item);
32
33    match export_internal_logic(attr_ts2, item_ts2) {
34        Ok(generated_code) => TokenStream::from(generated_code),
35        Err(err) => TokenStream::from(err.to_compile_error()),
36    }
37}
38
39#[cfg(test)]
40mod tests;