use crate::*;
use spin::Once;
use std::any::Any;
use std::mem::MaybeUninit;
type Builder<TSvc, TImpl> = ServiceDescriptorBuilder<TSvc, TImpl>;
#[inline(always)]
fn no_op(_services: &ServiceProvider) -> Ref<dyn Any> {
Ref::new(MaybeUninit::<Box<dyn Any>>::uninit())
}
#[inline]
pub fn singleton<TSvc: Any + ?Sized, TImpl>() -> ServiceDescriptorBuilder<TSvc, TImpl> {
Builder::new(ServiceLifetime::Singleton, Type::of::<TImpl>())
}
#[inline]
pub fn singleton_with_key<TKey, TSvc, TImpl>() -> ServiceDescriptorBuilder<TSvc, TImpl>
where
TSvc: Any + ?Sized,
{
Builder::keyed::<TKey>(ServiceLifetime::Singleton, Type::of::<TImpl>())
}
#[inline]
pub fn singleton_factory<T: Any + ?Sized, F>(factory: F) -> ServiceDescriptor
where
F: Fn(&ServiceProvider) -> Ref<T> + 'static,
{
Builder::<T, ()>::new(ServiceLifetime::Singleton, Type::factory_of::<T>()).from(factory)
}
#[inline]
pub fn singleton_with_key_factory<TKey, TSvc: Any + ?Sized, F>(factory: F) -> ServiceDescriptor
where
F: Fn(&ServiceProvider) -> Ref<TSvc> + 'static,
{
Builder::<TSvc, ()>::keyed::<TKey>(ServiceLifetime::Singleton, Type::factory_of::<TSvc>())
.from(factory)
}
#[inline]
pub fn singleton_as_self<T: Any>() -> ServiceDescriptorBuilder<T, T> {
Builder::new(ServiceLifetime::Singleton, Type::of::<T>())
}
#[inline]
pub fn scoped<TSvc: Any + ?Sized, TImpl>() -> ServiceDescriptorBuilder<TSvc, TImpl> {
Builder::new(ServiceLifetime::Scoped, Type::of::<TImpl>())
}
#[inline]
pub fn scoped_with_key<TKey, TSvc, TImpl>() -> ServiceDescriptorBuilder<TSvc, TImpl>
where
TSvc: Any + ?Sized,
{
Builder::keyed::<TKey>(ServiceLifetime::Scoped, Type::of::<TImpl>())
}
#[inline]
pub fn scoped_factory<T, F>(factory: F) -> ServiceDescriptor
where
T: Any + ?Sized,
F: Fn(&ServiceProvider) -> Ref<T> + 'static,
{
Builder::<T, ()>::new(ServiceLifetime::Scoped, Type::factory_of::<T>()).from(factory)
}
#[inline]
pub fn scoped_with_key_factory<TKey, TSvc, F>(factory: F) -> ServiceDescriptor
where
TSvc: Any + ?Sized,
F: Fn(&ServiceProvider) -> Ref<TSvc> + 'static,
{
Builder::<TSvc, ()>::keyed::<TKey>(ServiceLifetime::Scoped, Type::factory_of::<TSvc>())
.from(factory)
}
#[inline]
pub fn transient<TSvc: Any + ?Sized, TImpl>() -> ServiceDescriptorBuilder<TSvc, TImpl> {
Builder::new(ServiceLifetime::Transient, Type::of::<TImpl>())
}
#[inline]
pub fn transient_with_key<TKey, TSvc: Any + ?Sized, TImpl>() -> ServiceDescriptorBuilder<TSvc, TImpl>
{
Builder::keyed::<TKey>(ServiceLifetime::Transient, Type::of::<TImpl>())
}
#[inline]
pub fn transient_factory<T, F>(factory: F) -> ServiceDescriptor
where
T: Any + ?Sized,
F: Fn(&ServiceProvider) -> Ref<T> + 'static,
{
Builder::<T, ()>::new(ServiceLifetime::Transient, Type::factory_of::<T>()).from(factory)
}
#[inline]
pub fn transient_with_key_factory<TKey, TSvc: Any + ?Sized, F>(factory: F) -> ServiceDescriptor
where
F: Fn(&ServiceProvider) -> Ref<TSvc> + 'static,
{
Builder::<TSvc, ()>::keyed::<TKey>(ServiceLifetime::Transient, Type::factory_of::<TSvc>())
.from(factory)
}
#[inline]
pub fn transient_as_self<T: Any>() -> ServiceDescriptorBuilder<T, T> {
Builder::new(ServiceLifetime::Transient, Type::of::<T>())
}
#[inline]
pub fn transient_with_key_as_self<TKey, TSvc: Any>() -> ServiceDescriptorBuilder<TSvc, TSvc> {
Builder::keyed::<TKey>(ServiceLifetime::Transient, Type::of::<TSvc>())
}
#[inline]
pub fn existing<TSvc: Any + ?Sized, TImpl>(instance: Box<TSvc>) -> ServiceDescriptor {
ServiceDescriptor::new(
ServiceLifetime::Singleton,
Type::of::<TSvc>(),
Type::of::<TImpl>(),
Vec::with_capacity(0),
Once::initialized(Ref::new(Ref::<TSvc>::from(instance))),
Ref::new(no_op),
)
}
#[inline]
pub fn existing_as_self<T: Any>(instance: T) -> ServiceDescriptor {
ServiceDescriptor::new(
ServiceLifetime::Singleton,
Type::of::<T>(),
Type::of::<T>(),
Vec::with_capacity(0),
Once::initialized(Ref::new(Ref::from(instance))),
Ref::new(no_op),
)
}
#[inline]
pub fn existing_with_key<TKey, TSvc: Any + ?Sized, TImpl>(
instance: Box<TSvc>,
) -> ServiceDescriptor {
ServiceDescriptor::new(
ServiceLifetime::Singleton,
Type::keyed::<TKey, TSvc>(),
Type::of::<TImpl>(),
Vec::with_capacity(0),
Once::initialized(Ref::new(Ref::<TSvc>::from(instance))),
Ref::new(no_op),
)
}
#[inline]
pub fn existing_with_key_as_self<TKey, TSvc: Any>(instance: TSvc) -> ServiceDescriptor {
ServiceDescriptor::new(
ServiceLifetime::Singleton,
Type::keyed::<TKey, TSvc>(),
Type::of::<TSvc>(),
Vec::with_capacity(0),
Once::initialized(Ref::new(Ref::from(instance))),
Ref::new(no_op),
)
}
#[inline]
pub fn exactly_one<T: Any + ?Sized>() -> ServiceDependency {
ServiceDependency::new(Type::of::<T>(), ServiceCardinality::ExactlyOne)
}
#[inline]
pub fn exactly_one_with_key<TKey, TSvc: Any + ?Sized>() -> ServiceDependency {
ServiceDependency::new(Type::keyed::<TKey, TSvc>(), ServiceCardinality::ExactlyOne)
}
#[inline]
pub fn zero_or_one<T: Any + ?Sized>() -> ServiceDependency {
ServiceDependency::new(Type::of::<T>(), ServiceCardinality::ZeroOrOne)
}
#[inline]
pub fn zero_or_one_with_key<TKey, TSvc: Any + ?Sized>() -> ServiceDependency {
ServiceDependency::new(Type::keyed::<TKey, TSvc>(), ServiceCardinality::ZeroOrOne)
}
#[inline]
pub fn zero_or_more<T: Any + ?Sized>() -> ServiceDependency {
ServiceDependency::new(Type::of::<T>(), ServiceCardinality::ZeroOrMore)
}
#[inline]
pub fn zero_or_more_with_key<TKey, TSvc: Any + ?Sized>() -> ServiceDependency {
ServiceDependency::new(Type::keyed::<TKey, TSvc>(), ServiceCardinality::ZeroOrMore)
}