cgp-macro-lib 0.7.0

Context-generic programming core component macros implemented as a library.
Documentation
use quote::quote;
use syn::punctuated::Punctuated;
use syn::token::Comma;
use syn::{FieldValue, Ident, ItemImpl, ItemStruct, Type, parse2};

use crate::derive_builder::{field_to_member, field_value_expr, to_generic_args};

pub fn derive_finalize_build_impl(
    context_struct: &ItemStruct,
    builder_ident: &Ident,
) -> syn::Result<ItemImpl> {
    let context_ident = &context_struct.ident;
    let generics = &context_struct.generics;

    let mut generic_args = to_generic_args(generics)?;

    let mut builder_fields = <Punctuated<FieldValue, Comma>>::new();

    for (i, field) in context_struct.fields.iter().enumerate() {
        generic_args.args.push(parse2(quote! {
            IsPresent
        })?);

        let field_member = field_to_member(i, field);

        builder_fields.push(field_value_expr(
            field_member.clone(),
            quote! { self. #field_member },
        )?);
    }

    let (impl_generics, _, where_clause) = generics.split_for_impl();

    let builder_type: Type = parse2(quote! {
        #builder_ident #generic_args
    })?;

    let item_impl = parse2(quote! {
        impl #impl_generics FinalizeBuild for #builder_type
        #where_clause
        {
            fn finalize_build(self) -> Self::Target {
                #context_ident {
                    #builder_fields
                }
            }
        }
    })?;

    Ok(item_impl)
}