Skip to main content

arg_attr/
lib.rs

1#![doc = include_str!("../README.md")]
2
3use proc_macro as pm;
4use proc_macro2 as pm2;
5use quote::ToTokens;
6use syn::{
7    parse::{Parse, ParseStream},
8    punctuated::Punctuated,
9    token::Comma,
10    FnArg, ItemFn,
11};
12
13struct Args(Punctuated<FnArg, Comma>);
14
15impl Parse for Args {
16    fn parse(input: ParseStream) -> syn::Result<Self> {
17        Punctuated::<FnArg, Comma>::parse_terminated(input).map(Self)
18    }
19}
20
21#[proc_macro_attribute]
22pub fn args(meta: pm::TokenStream, input: pm::TokenStream) -> pm::TokenStream {
23    fn inner(meta: pm2::TokenStream, input: pm2::TokenStream) -> syn::Result<pm2::TokenStream> {
24        let mut input = syn::parse2::<syn::ItemFn>(input)?;
25        let Args(meta) = syn::parse2::<Args>(meta)?;
26        let ItemFn {
27            sig: syn::Signature { inputs, .. },
28            ..
29        } = &mut input;
30        *inputs = meta;
31        Ok(input.into_token_stream())
32    }
33    match inner(meta.into(), input.into()) {
34        Ok(output) => output.into(),
35        Err(error) => error.into_compile_error().into(),
36    }
37}