fn gen_async_buildable_impl()

in shed/facet/proc_macros/container_impl.rs [216:301]


fn gen_async_buildable_impl(
    facet_crate: &Ident,
    container_name: &Ident,
    members: &ContainerMembers,
) -> TokenStream {
    let facet_idents = &members.facet_idents;
    let facet_types = &members.facet_types;
    let field_idents = &members.field_idents;
    let field_inits = &members.field_inits;
    let delegate_idents = &members.delegate_idents;
    let delegate_types = &members.delegate_types;

    // Desugared async-trait so that the builder lifetime can be specified.
    quote! {
        impl<'builder, B> ::#facet_crate::AsyncBuildable<'builder, B> for #container_name
        where B: ::std::marker::Send + ::std::marker::Sync + ::#facet_crate::AsyncBuilder
            #( + ::#facet_crate::AsyncBuilderFor<::std::sync::Arc<#facet_types>> )*
            + 'builder,
            #( #delegate_types: ::#facet_crate::AsyncBuildable<'builder, B>, )*
        {
            fn build_async(mut builder: B) -> ::std::pin::Pin<::std::boxed::Box<
                dyn std::future::Future<
                    Output = ::std::result::Result<Self, ::#facet_crate::FactoryError>
                > + ::std::marker::Send + 'builder
            >>
            {
                let build = async move {
                    // Mark needed facets as needed.
                    Self::mark_needed(&mut builder);

                    // Build the needed facets.
                    <B as ::#facet_crate::AsyncBuilder>::build_needed(&mut builder).await?;

                    // Build ourself.
                    Ok(Self::construct(&builder))

                };
                ::std::boxed::Box::pin(build)
           }

           fn mark_needed(builder: &mut B) {
                // Mark facets we need as as needed.
                #(
                    <B as ::#facet_crate::AsyncBuilderFor<
                        ::std::sync::Arc<#facet_types>
                    >>::need(builder);
                )*

                // Mark facets our delegates need as needed.
                #(
                    <#delegate_types as ::#facet_crate::AsyncBuildable<'builder, B>>
                        ::mark_needed(builder);
                )*
           }

            fn construct(builder: &B) -> Self {
                // Build delegates.
                #(
                    let #delegate_idents =
                        <#delegate_types as ::#facet_crate::AsyncBuildable<'builder, B>>
                            ::construct(builder);
                )*

                // Get the facets out of the builder.
                #(
                    let #facet_idents =
                        <B as ::#facet_crate::AsyncBuilderFor<
                            ::std::sync::Arc<#facet_types>
                        >>::get(builder);
                )*

                // Initialize other fields.
                #(
                    let #field_idents = #field_inits;
                )*

                Self {
                    #( #delegate_idents, )*
                    #( #field_idents, )*
                    #( #facet_idents, )*
                }
            }
        }

    }
}