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}