di/
descriptor_builder.rs

1use crate::{
2    ServiceDependency, ServiceDescriptor, ServiceLifetime, ServiceProvider, Ref, Type,
3};
4use spin::Once;
5use std::any::Any;
6use std::marker::PhantomData;
7
8/// Represents a [`ServiceDescriptor`](crate::ServiceDescriptor) builder.
9pub struct ServiceDescriptorBuilder<TSvc: Any + ?Sized, TImpl> {
10    lifetime: ServiceLifetime,
11    service_type: Type,
12    implementation_type: Type,
13    dependencies: Vec<ServiceDependency>,
14    _marker_svc: PhantomData<TSvc>,
15    _marker_impl: PhantomData<TImpl>,
16}
17
18impl<TSvc: Any + ?Sized, TImpl> ServiceDescriptorBuilder<TSvc, TImpl> {
19    /// Defines the factory method used to activate the service and returns the [`ServiceDescriptor`](crate::ServiceDescriptor).
20    ///
21    /// # Arguments
22    ///
23    /// * `factory` - The factory method used to create the service
24    pub fn from(mut self, factory: impl Fn(&ServiceProvider) -> Ref<TSvc> + 'static) -> ServiceDescriptor {
25        ServiceDescriptor::new(
26            self.lifetime,
27            self.service_type,
28            self.implementation_type,
29            if self.dependencies.is_empty() {
30                Vec::with_capacity(0)
31            } else {
32                self.dependencies.shrink_to_fit();
33                self.dependencies
34            },
35            Once::new(),
36            Ref::new(move |sp| Ref::new(factory(sp))),
37        )
38    }
39
40    /// Defines a dependency used by the service.
41    ///
42    /// # Arguments
43    ///
44    /// * `dependency` - The [dependency](crate::ServiceDependency) associated with the service
45    pub fn depends_on(mut self, dependency: ServiceDependency) -> Self {
46        if !self.dependencies.contains(&dependency) {
47            self.dependencies.push(dependency);
48        }
49        self
50    }
51
52    /// Initializes a new service descriptor builder.
53    ///
54    /// # Arguments
55    ///
56    /// * `lifetime` - The [lifetime](crate::ServiceLifetime) of the service
57    /// * `implementation_type` - The service implementation [type](crate::Type)
58    pub fn new(lifetime: ServiceLifetime, implementation_type: Type) -> Self {
59        Self {
60            lifetime,
61            service_type: Type::of::<TSvc>(),
62            implementation_type,
63            dependencies: Vec::new(),
64            _marker_svc: PhantomData,
65            _marker_impl: PhantomData,
66        }
67    }
68
69    /// Initializes a new service descriptor builder.
70    ///
71    /// # Arguments
72    ///
73    /// * `lifetime` - The [lifetime](crate::ServiceLifetime) of the service
74    /// * `implementation_type` - The service implementation [type](crate::Type)
75    pub fn keyed<TKey>(lifetime: ServiceLifetime, implementation_type: Type) -> Self {
76        Self {
77            lifetime,
78            service_type: Type::keyed::<TKey, TSvc>(),
79            implementation_type,
80            dependencies: Vec::new(),
81            _marker_svc: PhantomData,
82            _marker_impl: PhantomData,
83        }
84    }
85}