use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use crate::codegen::CodeGenContext;
pub fn gen_inner_init(ctx: &CodeGenContext) -> TokenStream2 {
let has_trait_inject =
!ctx.trait_inject_fields.is_empty() || !ctx.required_trait_fields.is_empty() || !ctx.list_trait_fields.is_empty();
if !has_trait_inject && !ctx.comp_attr.has_init {
return quote! {};
}
let optional_assigns: Vec<TokenStream2> = ctx
.trait_inject_fields
.iter()
.map(|(fname, ty)| {
quote! {
self.#fname = Some(::tx_di_core::inject_trait_from_store::<#ty>(store));
}
})
.collect();
let required_assigns: Vec<TokenStream2> = ctx
.required_trait_fields
.iter()
.map(|(fname, ty)| {
quote! {
unsafe {
::core::ptr::write(
&mut self.#fname,
::tx_di_core::inject_trait_from_store::<#ty>(store),
);
}
}
})
.collect();
let list_assigns: Vec<TokenStream2> = ctx
.list_trait_fields
.iter()
.map(|(fname, ty)| {
quote! {
self.#fname = ::tx_di_core::inject_all_traits_from_store::<#ty>(store);
}
})
.collect();
if ctx.comp_attr.has_init {
quote! {
#[inline]
fn inner_init(&mut self, store: &::tx_di_core::Store) -> ::tx_di_core::RIE<()> {
#( #optional_assigns )*
#( #required_assigns )*
#( #list_assigns )*
self::init(self, store)
}
}
} else {
quote! {
#[inline]
fn inner_init(&mut self, store: &::tx_di_core::Store) -> ::tx_di_core::RIE<()> {
#( #optional_assigns )*
#( #required_assigns )*
#( #list_assigns )*
Ok(())
}
}
}
}