miwa_macros/
lib.rs

1mod config;
2mod extension;
3mod utils;
4
5use config::ExtensionConfig;
6use darling::FromDeriveInput;
7use darling::FromMeta;
8use extension::Extension;
9use syn::parse_macro_input;
10use syn::DeriveInput;
11use syn::ItemFn;
12
13macro_rules! parse_nested_meta {
14    ($ty:ty, $args:expr) => {{
15        let meta = match darling::ast::NestedMeta::parse_meta_list(proc_macro2::TokenStream::from(
16            $args,
17        )) {
18            Ok(v) => v,
19            Err(e) => {
20                return proc_macro::TokenStream::from(darling::Error::from(e).write_errors());
21            }
22        };
23
24        match <$ty>::from_list(&meta) {
25            Ok(object_args) => object_args,
26            Err(err) => return proc_macro::TokenStream::from(err.write_errors()),
27        }
28    }};
29}
30
31#[proc_macro_attribute]
32pub fn extension(
33    args: proc_macro::TokenStream,
34    original: proc_macro::TokenStream,
35) -> proc_macro::TokenStream {
36    let extension = parse_nested_meta!(Extension, args);
37    let item_fn: ItemFn = parse_macro_input!(original as ItemFn);
38    extension::generate(&extension, &item_fn)
39}
40
41#[proc_macro_derive(ExtensionConfig, attributes(config))]
42pub fn config(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
43    let object_args =
44        match ExtensionConfig::from_derive_input(&syn::parse_macro_input!(input as DeriveInput)) {
45            Ok(object_args) => object_args,
46            Err(err) => return proc_macro::TokenStream::from(err.write_errors()),
47        };
48    match config::generate(&object_args) {
49        Ok(ts) => ts.into(),
50        Err(e) => e.to_compile_error().into(),
51    }
52}