debate-derive 1.0.0

derive macro for the `debate` CLI arguments parser
Documentation
use darling::FromAttributes;
use heck::ToSnakeCase;
use itertools::Itertools as _;
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use syn::{Attribute, Field, Ident, Token, punctuated::Punctuated};

use super::common::struct_usage_items;
use crate::{
    common::{ParsedFieldInfo, RawParsedTypeAttr, compute_docs},
    generics::AngleBracedLifetime,
};

pub fn derive_usage_struct(
    name: &Ident,
    fields: &Punctuated<Field, Token![,]>,
    lifetime: Option<&AngleBracedLifetime>,
    attrs: &[Attribute],
) -> syn::Result<TokenStream2> {
    let fields: Vec<ParsedFieldInfo> = fields
        .iter()
        .map(ParsedFieldInfo::from_field)
        .try_collect()?;

    let docs = compute_docs(attrs)?;
    let docs = docs.quote();
    let attrs = RawParsedTypeAttr::from_attributes(attrs)?;
    let items = struct_usage_items(&fields, attrs.help_option());
    let command_name = name.to_string().to_snake_case();

    Ok(quote! {
        impl #lifetime ::debate::help::Usage for #name #lifetime {
            const NAME: &'static str = #command_name;
            const DESCRIPTION: ::debate::help::Description<'static> = #docs;
            const ITEMS: ::debate::help::UsageItems<'static> = ::debate::help::UsageItems::Parameters {
                parameters: #items,
            };
        }
    })
}