miwa-macros 0.1.0

Miwa macros
Documentation
mod config;
mod extension;
mod utils;

use config::ExtensionConfig;
use darling::FromDeriveInput;
use darling::FromMeta;
use extension::Extension;
use syn::parse_macro_input;
use syn::DeriveInput;
use syn::ItemFn;

macro_rules! parse_nested_meta {
    ($ty:ty, $args:expr) => {{
        let meta = match darling::ast::NestedMeta::parse_meta_list(proc_macro2::TokenStream::from(
            $args,
        )) {
            Ok(v) => v,
            Err(e) => {
                return proc_macro::TokenStream::from(darling::Error::from(e).write_errors());
            }
        };

        match <$ty>::from_list(&meta) {
            Ok(object_args) => object_args,
            Err(err) => return proc_macro::TokenStream::from(err.write_errors()),
        }
    }};
}

#[proc_macro_attribute]
pub fn extension(
    args: proc_macro::TokenStream,
    original: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
    let extension = parse_nested_meta!(Extension, args);
    let item_fn: ItemFn = parse_macro_input!(original as ItemFn);
    extension::generate(&extension, &item_fn)
}

#[proc_macro_derive(ExtensionConfig, attributes(config))]
pub fn config(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let object_args =
        match ExtensionConfig::from_derive_input(&syn::parse_macro_input!(input as DeriveInput)) {
            Ok(object_args) => object_args,
            Err(err) => return proc_macro::TokenStream::from(err.write_errors()),
        };
    match config::generate(&object_args) {
        Ok(ts) => ts.into(),
        Err(e) => e.to_compile_error().into(),
    }
}