1use darling::FromMeta;
3use proc_macro::TokenStream;
4use syn::{parse_macro_input, ItemImpl};
5
6use crate::utils::expand_with;
7
8mod args;
9mod from_ref;
10mod provider;
11mod utils;
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 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 TokenStream::from(err.write_errors()),
27 }
28 }};
29}
30
31#[proc_macro_attribute]
33#[allow(non_snake_case)]
34pub fn Provider(args: TokenStream, input: TokenStream) -> TokenStream {
35 let object_args = parse_nested_meta!(args::Provider, args);
36 let mut item_impl = parse_macro_input!(input as ItemImpl);
37 match provider::generate(&object_args, &mut item_impl) {
38 Ok(expanded) => expanded,
39 Err(err) => err.write_errors().into(),
40 }
41}
42
43#[proc_macro_derive(FromRef, attributes(from_ref))]
47pub fn derive_from_ref(item: TokenStream) -> TokenStream {
48 expand_with(item, from_ref::expand)
49}