// SPDX-License-Identifier: MIT // Copyright (c) 2023 Robin Jarry use proc_macro2::TokenStream; use proc_macro_error::abort_call_site; use quote::quote; use syn::{self, Data, DataStruct, DeriveInput, Field, Fields, Generics, Ident}; use crate::dummies; use crate::item::Item; pub fn derive_ini(input: &DeriveInput) -> TokenStream { let ident = &input.ident; match input.data { Data::Struct(DataStruct { fields: Fields::Named(ref fields), .. }) => { dummies::ini(ident); let item = Item::from_args_struct(input); let fields = fields .named .iter() .map(|field| { let item = Item::from_args_field(field); (field, item) }) .collect::>(); gen_for_struct(&item, ident, &input.generics, &fields) } _ => abort_call_site!("`#[derive(Ini)]` only supports non-tuple structs"), } } fn gen_for_struct( item: &Item, name: &Ident, generics: &Generics, fields: &[(&Field, Item)], ) -> TokenStream { let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let into_app = into_app::gen_for_struct(item, name, generics); let args = args::gen_for_struct(item, name, generics, fields); quote! { impl #impl_generics clap::Parser for #name #ty_generics #where_clause {} #into_app #args } }