Skip to main content

di/
activator.rs

1use crate::{Mut, Ref, RefMut, ServiceFactory, ServiceProvider, Type};
2use std::any::Any;
3
4macro_rules! new {
5    ($($traits:tt)+) => {
6        /// Creates a new activator using the specified factory methods to instantiate the service.
7        ///
8        /// # Arguments
9        ///
10        /// * `factory` - The factory method used to create a service instance
11        /// * `factory_mut` - The factory method used to create a mutable service instance
12        pub fn new<TSvc: ?Sized + $($traits)+, TImpl>(
13            factory: fn(&ServiceProvider) -> Ref<TSvc>,
14            factory_mut: fn(&ServiceProvider) -> RefMut<TSvc>,
15        ) -> Self {
16            Self {
17                service_type: Type::of::<TSvc>(),
18                service_type_mut: Type::of::<Mut<TSvc>>(),
19                implementation_type: Type::of::<TImpl>(),
20                factory: Ref::new(move |sp| Ref::new(factory(sp))),
21                factory_mut: Ref::new(move |sp| Ref::new(factory_mut(sp))),
22                mutable: false,
23            }
24        }
25    };
26}
27
28/// Represents an activator for a service instance.
29pub struct Activator {
30    service_type: Type,
31    service_type_mut: Type,
32    implementation_type: Type,
33    factory: Ref<ServiceFactory>,
34    factory_mut: Ref<ServiceFactory>,
35    mutable: bool,
36}
37
38impl Activator {
39    /// Gets the [service type](Type) associated with the service descriptor.
40    pub fn service_type(&self) -> &Type {
41        if self.mutable {
42            &self.service_type_mut
43        } else {
44            &self.service_type
45        }
46    }
47
48    /// Gets the [implementation type](Type) associated with the service descriptor.
49    #[inline]
50    pub fn implementation_type(&self) -> &Type {
51        &self.implementation_type
52    }
53
54    /// Sets a value indicating whether the activated instance should be mutable.
55    #[inline]
56    pub fn as_mut(&mut self) {
57        self.mutable = true;
58    }
59
60    /// Gets the [factory](ServiceFactory) method the activator represents.
61    pub fn factory(&self) -> Ref<ServiceFactory> {
62        if self.mutable {
63            self.factory_mut.clone()
64        } else {
65            self.factory.clone()
66        }
67    }
68
69    cfg_if::cfg_if! {
70        if #[cfg(feature = "async")] {
71            new!(Any + Send + Sync);
72        } else {
73            new!(Any);
74        }
75    }
76}