cgp-component-macro-lib 0.3.0

Context-generic programming core component macros implemented as a library.
Documentation
use alloc::string::ToString;

use proc_macro2::TokenStream;
use quote::quote;
use syn::{parse_quote, Ident, ItemImpl, ItemTrait};

use crate::getter_component::getter_field::GetterField;
use crate::getter_component::symbol::symbol_from_string;

pub fn derive_blanket_impl(
    context_type: &Ident,
    consumer_trait: &ItemTrait,
    fields: &[GetterField],
) -> ItemImpl {
    let consumer_name = &consumer_trait.ident;

    let mut constraints = consumer_trait.supertraits.clone();

    let mut methods: TokenStream = TokenStream::new();

    for field in fields {
        let field_name = &field.field_name;
        let provider_type = &field.provider_type;
        let field_symbol = symbol_from_string(&field.field_name.to_string());

        if field.field_mut.is_none() {
            constraints.push(parse_quote! {
                HasField< #field_symbol, Value = #provider_type >
            });

            methods.extend(quote! {
                fn #field_name( &self ) -> & #provider_type {
                    self.get_field( ::core::marker::PhantomData::< #field_symbol > )
                }
            });
        } else {
            constraints.push(parse_quote! {
                HasFieldMut< #field_symbol, Value = #provider_type >
            });

            methods.extend(quote! {
                fn #field_name( &mut self ) -> &mut #provider_type {
                    self.get_field_mut( ::core::marker::PhantomData::< #field_symbol > )
                }
            });
        }
    }

    parse_quote! {
        impl< #context_type > #consumer_name for #context_type
        where
            #context_type: #constraints
        {
            #methods
        }
    }
}