use std::any::TypeId;
use std::sync::Arc;
use nest_rs_core::Container;
use nest_rs_exception_filters::ExceptionFilterErased;
use nest_rs_filters::Filter;
use nest_rs_interceptors::Interceptor;
use nest_rs_pipes::GlobalPipe;
use nest_rs_core::layer_chain::{LayerSite, ResolvedLayer};
use crate::Guard;
pub struct ScopedLayerSpec<L: ?Sized> {
pub type_id: TypeId,
pub name: &'static str,
pub resolve: fn(&Container) -> Option<Arc<L>>,
}
pub type ScopedGuardSpec = ScopedLayerSpec<dyn Guard>;
pub type ScopedPipeSpec = ScopedLayerSpec<dyn GlobalPipe>;
pub type ScopedExceptionFilterSpec = ScopedLayerSpec<dyn ExceptionFilterErased>;
pub type ScopedInterceptorSpec = ScopedLayerSpec<dyn Interceptor>;
pub type ScopedFilterSpec = ScopedLayerSpec<dyn Filter>;
pub(crate) fn resolve_specs<L: ?Sized>(
container: &Container,
specs: &[ScopedLayerSpec<L>],
source: LayerSite,
) -> Vec<ResolvedLayer<L>> {
specs
.iter()
.filter_map(|spec| {
(spec.resolve)(container).map(|layer| ResolvedLayer {
type_id: spec.type_id,
name: spec.name,
source,
layer,
})
})
.collect()
}