interoptopus_proc_impl 0.16.0-alpha.20

Macros to produce Interoptopus item info.
Documentation
#![doc = include_str!("../README.md")]
#![allow(clippy::needless_pass_by_value)]

extern crate proc_macro; // Apparently needed to be imported like this.

mod constant;
mod docs;
mod forbidden;
mod function;
mod runtime;
mod service;
mod skip;
mod types;

mod plugin;

use proc_macro2::TokenStream;
use quote::quote;
use syn::{Item, parse2};

#[must_use]
pub fn ffi(attr: TokenStream, item: TokenStream) -> TokenStream {
    // Helper function to handle results with consistent error formatting
    let handle_result = |result: syn::Result<TokenStream>| match result {
        Ok(tokens) => tokens,
        Err(err) => {
            let error = err.to_compile_error();
            quote! {
                #item
                #error
            }
        }
    };

    // Parse and forward to appropriate macro based on item type
    let result = parse2::<Item>(item.clone()).and_then(|parsed_item| match parsed_item {
        Item::Struct(_) | Item::Enum(_) => types::ffi(attr, item.clone()),
        Item::Fn(_) => function::ffi(attr, item.clone()),
        Item::Const(_) => constant::ffi(attr, item.clone()),
        Item::Impl(_) => service::ffi(attr, item.clone()),
        _ => Err(syn::Error::new_spanned(&parsed_item, "#[ffi] can only be applied to structs, enums, functions, const, or impl blocks")),
    });

    handle_result(result)
}

#[must_use]
pub fn derive_async_runtime(item: TokenStream) -> TokenStream {
    let handle_result = |result: syn::Result<TokenStream>| match result {
        Ok(tokens) => tokens,
        Err(err) => err.to_compile_error(),
    };

    handle_result(runtime::derive_async_runtime(item))
}

#[must_use]
pub fn plugin(input: TokenStream) -> TokenStream {
    plugin::plugin(input)
}