1use crate::*;
2use spin::Once;
3use std::any::Any;
4use std::mem::MaybeUninit;
5
6type Builder<TSvc, TImpl> = ServiceDescriptorBuilder<TSvc, TImpl>;
7
8#[inline(always)]
9fn no_op(_services: &ServiceProvider) -> Ref<dyn Any> {
10 Ref::new(MaybeUninit::<Box<dyn Any>>::uninit())
11}
12
13#[inline]
15pub fn singleton<TSvc: Any + ?Sized, TImpl>() -> ServiceDescriptorBuilder<TSvc, TImpl> {
16 Builder::new(ServiceLifetime::Singleton, Type::of::<TImpl>())
17}
18
19#[inline]
21pub fn singleton_with_key<TKey, TSvc, TImpl>() -> ServiceDescriptorBuilder<TSvc, TImpl>
22where
23 TSvc: Any + ?Sized,
24{
25 Builder::keyed::<TKey>(ServiceLifetime::Singleton, Type::of::<TImpl>())
26}
27
28#[inline]
34pub fn singleton_factory<T: Any + ?Sized, F>(factory: F) -> ServiceDescriptor
35where
36 F: Fn(&ServiceProvider) -> Ref<T> + 'static,
37{
38 Builder::<T, ()>::new(ServiceLifetime::Singleton, Type::factory_of::<T>()).from(factory)
39}
40
41#[inline]
47pub fn singleton_with_key_factory<TKey, TSvc: Any + ?Sized, F>(factory: F) -> ServiceDescriptor
48where
49 F: Fn(&ServiceProvider) -> Ref<TSvc> + 'static,
50{
51 Builder::<TSvc, ()>::keyed::<TKey>(ServiceLifetime::Singleton, Type::factory_of::<TSvc>())
52 .from(factory)
53}
54
55#[inline]
61pub fn singleton_as_self<T: Any>() -> ServiceDescriptorBuilder<T, T> {
62 Builder::new(ServiceLifetime::Singleton, Type::of::<T>())
63}
64
65#[inline]
67pub fn scoped<TSvc: Any + ?Sized, TImpl>() -> ServiceDescriptorBuilder<TSvc, TImpl> {
68 Builder::new(ServiceLifetime::Scoped, Type::of::<TImpl>())
69}
70
71#[inline]
73pub fn scoped_with_key<TKey, TSvc, TImpl>() -> ServiceDescriptorBuilder<TSvc, TImpl>
74where
75 TSvc: Any + ?Sized,
76{
77 Builder::keyed::<TKey>(ServiceLifetime::Scoped, Type::of::<TImpl>())
78}
79
80#[inline]
86pub fn scoped_factory<T, F>(factory: F) -> ServiceDescriptor
87where
88 T: Any + ?Sized,
89 F: Fn(&ServiceProvider) -> Ref<T> + 'static,
90{
91 Builder::<T, ()>::new(ServiceLifetime::Scoped, Type::factory_of::<T>()).from(factory)
92}
93
94#[inline]
100pub fn scoped_with_key_factory<TKey, TSvc, F>(factory: F) -> ServiceDescriptor
101where
102 TSvc: Any + ?Sized,
103 F: Fn(&ServiceProvider) -> Ref<TSvc> + 'static,
104{
105 Builder::<TSvc, ()>::keyed::<TKey>(ServiceLifetime::Scoped, Type::factory_of::<TSvc>())
106 .from(factory)
107}
108
109#[inline]
111pub fn transient<TSvc: Any + ?Sized, TImpl>() -> ServiceDescriptorBuilder<TSvc, TImpl> {
112 Builder::new(ServiceLifetime::Transient, Type::of::<TImpl>())
113}
114
115#[inline]
117pub fn transient_with_key<TKey, TSvc: Any + ?Sized, TImpl>() -> ServiceDescriptorBuilder<TSvc, TImpl>
118{
119 Builder::keyed::<TKey>(ServiceLifetime::Transient, Type::of::<TImpl>())
120}
121
122#[inline]
128pub fn transient_factory<T, F>(factory: F) -> ServiceDescriptor
129where
130 T: Any + ?Sized,
131 F: Fn(&ServiceProvider) -> Ref<T> + 'static,
132{
133 Builder::<T, ()>::new(ServiceLifetime::Transient, Type::factory_of::<T>()).from(factory)
134}
135
136#[inline]
142pub fn transient_with_key_factory<TKey, TSvc: Any + ?Sized, F>(factory: F) -> ServiceDescriptor
143where
144 F: Fn(&ServiceProvider) -> Ref<TSvc> + 'static,
145{
146 Builder::<TSvc, ()>::keyed::<TKey>(ServiceLifetime::Transient, Type::factory_of::<TSvc>())
147 .from(factory)
148}
149
150#[inline]
156pub fn transient_as_self<T: Any>() -> ServiceDescriptorBuilder<T, T> {
157 Builder::new(ServiceLifetime::Transient, Type::of::<T>())
158}
159
160#[inline]
166pub fn transient_with_key_as_self<TKey, TSvc: Any>() -> ServiceDescriptorBuilder<TSvc, TSvc> {
167 Builder::keyed::<TKey>(ServiceLifetime::Transient, Type::of::<TSvc>())
168}
169
170#[inline]
180pub fn existing<TSvc: Any + ?Sized, TImpl>(instance: Box<TSvc>) -> ServiceDescriptor {
181 ServiceDescriptor::new(
182 ServiceLifetime::Singleton,
183 Type::of::<TSvc>(),
184 Type::of::<TImpl>(),
185 Vec::with_capacity(0),
186 Once::initialized(Ref::new(Ref::<TSvc>::from(instance))),
187 Ref::new(no_op),
188 )
189}
190
191#[inline]
201pub fn existing_as_self<T: Any>(instance: T) -> ServiceDescriptor {
202 ServiceDescriptor::new(
203 ServiceLifetime::Singleton,
204 Type::of::<T>(),
205 Type::of::<T>(),
206 Vec::with_capacity(0),
207 Once::initialized(Ref::new(Ref::from(instance))),
208 Ref::new(no_op),
209 )
210}
211
212#[inline]
222pub fn existing_with_key<TKey, TSvc: Any + ?Sized, TImpl>(
223 instance: Box<TSvc>,
224) -> ServiceDescriptor {
225 ServiceDescriptor::new(
226 ServiceLifetime::Singleton,
227 Type::keyed::<TKey, TSvc>(),
228 Type::of::<TImpl>(),
229 Vec::with_capacity(0),
230 Once::initialized(Ref::new(Ref::<TSvc>::from(instance))),
231 Ref::new(no_op),
232 )
233}
234
235#[inline]
245pub fn existing_with_key_as_self<TKey, TSvc: Any>(instance: TSvc) -> ServiceDescriptor {
246 ServiceDescriptor::new(
247 ServiceLifetime::Singleton,
248 Type::keyed::<TKey, TSvc>(),
249 Type::of::<TSvc>(),
250 Vec::with_capacity(0),
251 Once::initialized(Ref::new(Ref::from(instance))),
252 Ref::new(no_op),
253 )
254}
255
256#[inline]
258pub fn exactly_one<T: Any + ?Sized>() -> ServiceDependency {
259 ServiceDependency::new(Type::of::<T>(), ServiceCardinality::ExactlyOne)
260}
261
262#[inline]
264pub fn exactly_one_with_key<TKey, TSvc: Any + ?Sized>() -> ServiceDependency {
265 ServiceDependency::new(Type::keyed::<TKey, TSvc>(), ServiceCardinality::ExactlyOne)
266}
267
268#[inline]
270pub fn zero_or_one<T: Any + ?Sized>() -> ServiceDependency {
271 ServiceDependency::new(Type::of::<T>(), ServiceCardinality::ZeroOrOne)
272}
273
274#[inline]
276pub fn zero_or_one_with_key<TKey, TSvc: Any + ?Sized>() -> ServiceDependency {
277 ServiceDependency::new(Type::keyed::<TKey, TSvc>(), ServiceCardinality::ZeroOrOne)
278}
279
280#[inline]
282pub fn zero_or_more<T: Any + ?Sized>() -> ServiceDependency {
283 ServiceDependency::new(Type::of::<T>(), ServiceCardinality::ZeroOrMore)
284}
285
286#[inline]
288pub fn zero_or_more_with_key<TKey, TSvc: Any + ?Sized>() -> ServiceDependency {
289 ServiceDependency::new(Type::keyed::<TKey, TSvc>(), ServiceCardinality::ZeroOrMore)
290}