use std::sync::Arc;
use crate::injection_context::InjectionContext;
use crate::*;
#[derive(Clone)]
pub struct Catalog(pub(crate) Arc<CatalogImpl>);
impl Catalog {
pub(crate) fn new(pimpl: Arc<CatalogImpl>) -> Self {
Self(pimpl)
}
pub fn builder() -> CatalogBuilder {
CatalogBuilder::new()
}
pub fn builder_chained(&self) -> CatalogBuilder {
CatalogBuilder::new_chained(self)
}
pub fn weak_ref(&self) -> CatalogWeakRef {
CatalogWeakRef::new(&self.0)
}
#[inline(always)]
pub fn builders<'a>(&'a self) -> Box<dyn Iterator<Item = &'a dyn Builder> + 'a> {
self.0.builders()
}
#[inline(always)]
pub fn builders_for<'a, Iface>(
&'a self,
) -> Box<dyn Iterator<Item = TypecastBuilder<'a, Iface>> + 'a>
where
Iface: 'static + ?Sized,
{
self.0.builders_for()
}
#[inline(always)]
pub fn builders_for_with_meta<'a, Iface, Meta>(
&'a self,
pred: impl Fn(&Meta) -> bool + Copy + 'a,
) -> Box<dyn Iterator<Item = TypecastBuilder<'a, Iface>> + 'a>
where
Iface: 'static + ?Sized,
Meta: 'static,
{
self.0.builders_for_with_meta(pred)
}
#[inline(always)]
pub fn get<Spec>(&self) -> Result<Spec::ReturnType, InjectionError>
where
Spec: DependencySpec + 'static,
{
self.get_with_context::<Spec>(&InjectionContext::new_root())
}
#[inline(always)]
pub fn get_with_context<Spec>(
&self,
ctx: &InjectionContext,
) -> Result<Spec::ReturnType, InjectionError>
where
Spec: DependencySpec + 'static,
{
Spec::get(self, &ctx.push_resolve::<Spec>())
}
#[inline(always)]
pub fn get_one<Iface>(&self) -> Result<Arc<Iface>, InjectionError>
where
Iface: 'static + ?Sized + Send + Sync,
{
self.get::<OneOf<Iface>>()
}
#[cfg(feature = "tokio")]
pub async fn scope<F, R>(&self, f: F) -> R
where
F: std::future::Future<Output = R>,
{
CURRENT_CATALOG.scope(self.clone(), f).await
}
#[cfg(feature = "tokio")]
pub fn current() -> Catalog {
CURRENT_CATALOG.get()
}
}
impl std::fmt::Debug for Catalog {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Catalog(0x{:x})",
self.0.as_ref() as *const CatalogImpl as usize
)
}
}
#[cfg(feature = "tokio")]
tokio::task_local! {
pub(crate) static CURRENT_CATALOG: Catalog;
}