di/
builder.rs

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/// Initializes a new singleton [`ServiceDescriptorBuilder`](crate::ServiceDescriptorBuilder).
14#[inline]
15pub fn singleton<TSvc: Any + ?Sized, TImpl>() -> ServiceDescriptorBuilder<TSvc, TImpl> {
16    Builder::new(ServiceLifetime::Singleton, Type::of::<TImpl>())
17}
18
19/// Initializes a new keyed singleton [`ServiceDescriptorBuilder`](crate::ServiceDescriptorBuilder).
20#[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/// Initializes a new singleton [`ServiceDescriptor`](crate::ServiceDescriptor).
29///
30/// # Arguments
31///
32/// * `factory` - The factory method used to create the service
33#[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/// Initializes a new keyed singleton [`ServiceDescriptor`](crate::ServiceDescriptor).
42///
43/// # Arguments
44///
45/// * `factory` - The factory method used to create the service
46#[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/// Initializes a new singleton [`ServiceDescriptorBuilder`](crate::ServiceDescriptorBuilder).
56///
57/// # Remarks
58///
59/// This function maps a concrete type to itself rather than a trait.
60#[inline]
61pub fn singleton_as_self<T: Any>() -> ServiceDescriptorBuilder<T, T> {
62    Builder::new(ServiceLifetime::Singleton, Type::of::<T>())
63}
64
65/// Initializes a new scoped [`ServiceDescriptorBuilder`](crate::ServiceDescriptorBuilder).
66#[inline]
67pub fn scoped<TSvc: Any + ?Sized, TImpl>() -> ServiceDescriptorBuilder<TSvc, TImpl> {
68    Builder::new(ServiceLifetime::Scoped, Type::of::<TImpl>())
69}
70
71/// Initializes a new scoped keyed [`ServiceDescriptorBuilder`](crate::ServiceDescriptorBuilder).
72#[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/// Initializes a new scoped [`ServiceDescriptor`](crate::ServiceDescriptor).
81///
82/// # Arguments
83///
84/// * `factory` - The factory method used to create the service
85#[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/// Initializes a new keyed scoped [`ServiceDescriptor`](crate::ServiceDescriptor).
95///
96/// # Arguments
97///
98/// * `factory` - The factory method used to create the service
99#[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/// Initializes a new transient [`ServiceDescriptorBuilder`](crate::ServiceDescriptorBuilder).
110#[inline]
111pub fn transient<TSvc: Any + ?Sized, TImpl>() -> ServiceDescriptorBuilder<TSvc, TImpl> {
112    Builder::new(ServiceLifetime::Transient, Type::of::<TImpl>())
113}
114
115/// Initializes a new keyed transient [`ServiceDescriptorBuilder`](crate::ServiceDescriptorBuilder).
116#[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/// Initializes a new transient [`ServiceDescriptor`](crate::ServiceDescriptor).
123///
124/// # Arguments
125///
126/// * `factory` - The factory method used to create the service
127#[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/// Initializes a new keyed transient [`ServiceDescriptor`](crate::ServiceDescriptor).
137///
138/// # Arguments
139///
140/// * `factory` - The factory method used to create the service
141#[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/// Initializes a new transient [`ServiceDescriptorBuilder`](crate::ServiceDescriptorBuilder).
151///
152/// # Remarks
153///
154/// This function maps a concrete type to itself rather than a trait.
155#[inline]
156pub fn transient_as_self<T: Any>() -> ServiceDescriptorBuilder<T, T> {
157    Builder::new(ServiceLifetime::Transient, Type::of::<T>())
158}
159
160/// Initializes a new transient keyed [`ServiceDescriptorBuilder`](crate::ServiceDescriptorBuilder).
161///
162/// # Remarks
163///
164/// This function maps a concrete type to itself rather than a trait.
165#[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/// Creates a new singleton [`ServiceDescriptor`](crate::ServiceDescriptor) for an existing service instance.
171///
172/// # Arguments
173///
174/// * `instance` - The existing service instance
175///
176/// # Remarks
177///
178/// This function maps an existing instance to a trait.
179#[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/// Creates a new singleton [`ServiceDescriptor`](crate::ServiceDescriptor) for an existing service instance.
192///
193/// # Arguments
194///
195/// * `instance` - The existing service instance
196///
197/// # Remarks
198///
199/// This function maps an existing instance to itself rather than a trait.
200#[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/// Creates a new singleton [`ServiceDescriptor`](crate::ServiceDescriptor) for an existing service instance with a key.
213///
214/// # Arguments
215///
216/// * `instance` - The existing service instance
217///
218/// # Remarks
219///
220/// This function maps an existing instance to a trait.
221#[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/// Creates a new singleton [`ServiceDescriptor`](crate::ServiceDescriptor) for an existing service instance with a key.
236///
237/// # Arguments
238///
239/// * `instance` - The existing service instance
240///
241/// # Remarks
242///
243/// This function maps an existing instance to itself rather than a trait.
244#[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/// Creates a new [`ServiceDependency`](crate::ServiceDependency) with a cardinality of exactly one (1:1).
257#[inline]
258pub fn exactly_one<T: Any + ?Sized>() -> ServiceDependency {
259    ServiceDependency::new(Type::of::<T>(), ServiceCardinality::ExactlyOne)
260}
261
262/// Creates a new keyed [`ServiceDependency`](crate::ServiceDependency) with a cardinality of exactly one (1:1).
263#[inline]
264pub fn exactly_one_with_key<TKey, TSvc: Any + ?Sized>() -> ServiceDependency {
265    ServiceDependency::new(Type::keyed::<TKey, TSvc>(), ServiceCardinality::ExactlyOne)
266}
267
268/// Creates a new [`ServiceDependency`](crate::ServiceDependency) with a cardinality of zero or one (0:1).
269#[inline]
270pub fn zero_or_one<T: Any + ?Sized>() -> ServiceDependency {
271    ServiceDependency::new(Type::of::<T>(), ServiceCardinality::ZeroOrOne)
272}
273
274/// Creates a new keyed [`ServiceDependency`](crate::ServiceDependency) with a cardinality of zero or one (0:1).
275#[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/// Creates a new [`ServiceDependency`](crate::ServiceDependency) with a cardinality of zero or more (0:*).
281#[inline]
282pub fn zero_or_more<T: Any + ?Sized>() -> ServiceDependency {
283    ServiceDependency::new(Type::of::<T>(), ServiceCardinality::ZeroOrMore)
284}
285
286/// Creates a new keyed [`ServiceDependency`](crate::ServiceDependency) with a cardinality of zero or more (0:*).
287#[inline]
288pub fn zero_or_more_with_key<TKey, TSvc: Any + ?Sized>() -> ServiceDependency {
289    ServiceDependency::new(Type::keyed::<TKey, TSvc>(), ServiceCardinality::ZeroOrMore)
290}