nakago_derive/
lib.rs

1//! # Derive
2use 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/// Derive `Provider` trait for a struct.
32#[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/// Derive an implementation of [`FromRef`] for each field in a struct.
44///
45/// [`FromRef`]: https://docs.rs/axum/0.7/axum/extract/trait.FromRef.html
46#[proc_macro_derive(FromRef, attributes(from_ref))]
47pub fn derive_from_ref(item: TokenStream) -> TokenStream {
48    expand_with(item, from_ref::expand)
49}