aboutsummaryrefslogtreecommitdiff
path: root/derive-macro/src/derives.rs
diff options
context:
space:
mode:
Diffstat (limited to 'derive-macro/src/derives.rs')
-rw-r--r--derive-macro/src/derives.rs54
1 files changed, 54 insertions, 0 deletions
diff --git a/derive-macro/src/derives.rs b/derive-macro/src/derives.rs
new file mode 100644
index 00000000..fdb83a0d
--- /dev/null
+++ b/derive-macro/src/derives.rs
@@ -0,0 +1,54 @@
+// 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::<Vec<_>>();
+ 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
+ }
+}