di/description/
descriptor.rs1use super::ServiceLifetime::{self, *};
2use crate::{Ref, ServiceDependency, ServiceFactory, ServiceProvider, Type};
3use std::any::Any;
4use std::sync::OnceLock;
5
6cfg_if::cfg_if! {
7 if #[cfg(feature = "async")] {
8 macro_rules! service {
9 () => { dyn Any + Send + Sync };
10 }
11 } else {
12 macro_rules! service {
13 () => { dyn Any };
14 }
15 }
16}
17
18pub struct ServiceDescriptor {
20 lifetime: ServiceLifetime,
21 service_type: Type,
22 implementation_type: Type,
23 dependencies: Vec<ServiceDependency>,
24 factory: Ref<ServiceFactory>,
25 instance: Ref<OnceLock<Ref<service!()>>>,
26}
27
28impl ServiceDescriptor {
29 #[cfg(any(feature = "builder", feature = "inject"))]
30 pub(crate) fn new(
31 lifetime: ServiceLifetime,
32 service_type: Type,
33 implementation_type: Type,
34 dependencies: Vec<ServiceDependency>,
35 instance: OnceLock<Ref<service!()>>,
36 factory: Ref<ServiceFactory>,
37 ) -> Self {
38 Self {
39 lifetime,
40 service_type,
41 implementation_type,
42 dependencies,
43 instance: Ref::new(instance),
44 factory,
45 }
46 }
47
48 #[inline]
50 pub fn lifetime(&self) -> ServiceLifetime {
51 self.lifetime
52 }
53
54 #[inline]
56 pub fn service_type(&self) -> &Type {
57 &self.service_type
58 }
59
60 #[inline]
62 pub fn implementation_type(&self) -> &Type {
63 &self.implementation_type
64 }
65
66 #[inline]
68 pub fn dependencies(&self) -> &[ServiceDependency] {
69 &self.dependencies
70 }
71
72 pub fn get(&self, services: &ServiceProvider) -> Ref<service!()> {
78 if self.lifetime == Transient {
79 return (self.factory)(services);
80 }
81
82 self.instance.get_or_init(|| (self.factory)(services)).clone()
83 }
84
85 pub(crate) fn clone_with(&self, dependencies: bool) -> Self {
86 Self {
87 lifetime: self.lifetime,
88 service_type: self.service_type.clone(),
89 implementation_type: self.implementation_type.clone(),
90 dependencies: if dependencies {
91 self.dependencies.clone()
92 } else {
93 Vec::new()
94 },
95 instance: if self.lifetime == Singleton {
96 self.instance.clone()
97 } else {
98 Ref::new(OnceLock::new())
99 },
100 factory: self.factory.clone(),
101 }
102 }
103}
104
105impl Clone for ServiceDescriptor {
106 #[inline]
107 fn clone(&self) -> Self {
108 self.clone_with(true)
110 }
111}