froodi 1.0.0-beta.18

An ergonomic Rust IoC container
Documentation
use alloc::collections::btree_map::BTreeMap;
use core::{future::Future, pin::Pin};

use crate::{
    any::TypeInfo,
    async_impl::{
        self,
        finalizer::boxed_finalizer_factory,
        instantiator::{boxed_instantiator, Instantiator},
        registry::InstantiatorData,
        Finalizer, RegistryWithSync,
    },
    dependency_resolver::DependencyResolver,
    macros_utils::types::{RegistryKind, RegistryKindOrEntry},
    utils::{
        hlist,
        thread_safety::{SendSafety, SyncSafety},
    },
    Config, InstantiateErrorKind, Registry, ResolveErrorKind, Scope, Scopes,
};

#[inline]
#[must_use]
#[doc(hidden)]
pub fn build_registry<H, S, const N: usize>((_, iterable): (S, H)) -> RegistryWithSync
where
    S: Scope + Scopes<N, Scope = S>,
    H: hlist::IntoIterator<RegistryKindOrEntry>,
{
    let mut entries = BTreeMap::new();
    let mut sync_entries = BTreeMap::new();
    for registry_kind_or_entry in iterable.into_iter() {
        match registry_kind_or_entry {
            RegistryKindOrEntry::Kind(RegistryKind::Sync(registry)) => {
                sync_entries.extend(registry.entries);
            }
            RegistryKindOrEntry::Kind(RegistryKind::Async(registry)) => {
                entries.extend(registry.entries);
            }
            RegistryKindOrEntry::Kind(RegistryKind::AsyncWithSync(RegistryWithSync { registry, sync })) => {
                entries.extend(registry.entries);
                sync_entries.extend(sync.entries);
            }
            RegistryKindOrEntry::Entry((key, value)) => {
                entries.insert(key, value);
            }
        }
    }
    RegistryWithSync {
        registry: async_impl::Registry::new::<S, S, N>(entries),
        sync: Registry::new::<S, S, N>(sync_entries),
    }
}

#[inline]
#[must_use]
#[doc(hidden)]
pub fn make_entry<Inst, Deps, Fin>(scope: impl Scope, inst: Inst, config: Option<Config>, fin: Option<Fin>) -> (TypeInfo, InstantiatorData)
where
    Inst: Instantiator<Deps, Error = InstantiateErrorKind> + SendSafety + SyncSafety,
    Inst::Provides: SendSafety + SyncSafety,
    Deps: DependencyResolver<Error = ResolveErrorKind>,
    Fin: Finalizer<Inst::Provides> + SendSafety + SyncSafety,
{
    (
        TypeInfo::of::<Inst::Provides>(),
        InstantiatorData {
            dependencies: Inst::dependencies(),
            instantiator: boxed_instantiator(inst),
            finalizer: fin.map(boxed_finalizer_factory),
            config: config.unwrap_or_default(),
            scope_data: scope.into(),
        },
    )
}

#[cfg(feature = "thread_safe")]
pub type FinDummy<T> = fn(T) -> Pin<super::aliases::Box<dyn Future<Output = ()> + Send>>;
#[cfg(not(feature = "thread_safe"))]
pub type FinDummy<T> = fn(T) -> Pin<super::aliases::Box<dyn Future<Output = ()>>>;