quick-impl 0.2.1

Quickly implement usual methods and traits for enums and structs.
Documentation
use proc_macro2::{Ident, Span, TokenStream};
use quote::quote;
use syn::{ItemEnum, LitStr, Variant};

use crate::{
    config::Config,
    ctx::Context,
    idents::config::CONFIG_DOC,
    order::OrderTrait,
    tokens::{get_delimiter, with_delimiter},
};

const DEFAULT_DOC: &str = "Creates a [`{}::{}`] variant with the default associated data.";

pub fn expand_default(
    input: &ItemEnum,
    variant: &Variant,
    order: &OrderTrait,
) -> syn::Result<TokenStream> {
    let mut config = Config::new(&order.config, None)?;

    let doc = config.get_formatted_lit_str(
        CONFIG_DOC,
        LitStr::new(DEFAULT_DOC, Span::call_site()),
        [&input.ident.to_string(), &variant.ident.to_string()],
    )?;

    config.finish()?;

    let fields = &variant.fields;
    let delimiter = get_delimiter(fields);

    let variant_ident = &variant.ident;
    let trait_ident = Ident::new("Default", order.ident.span());
    let method_ident = Ident::new("default", order.ident.span());

    let default = quote! { ::core::default:: #trait_ident :: #method_ident () };
    let mut default_data = TokenStream::new();
    let mut where_clause = quote! { where };

    for field in &variant.fields {
        let field_ty = &field.ty;
        if let Some(ident) = &field.ident {
            default_data.extend(quote! { #ident : });
        }
        default_data.extend(quote! { #default, });
        where_clause.extend(quote! { #field_ty : ::core::default:: #trait_ident, });
    }
    let default_data = with_delimiter(default_data, delimiter);

    let content = quote! {
        #[doc = #doc]
        #[inline]
        fn #method_ident () -> Self {
            Self::#variant_ident #default_data
        }
    };

    Ok(input.in_impl(
        quote! { ::core::default::#trait_ident for },
        &content,
        Some(syn::parse2(where_clause).unwrap()),
    ))
}