spring/plugin/
mod.rs

1#![doc = include_str!("../../Plugin.md")]
2
3/// Component definition
4pub mod component;
5/// Lazy component loading for circular dependencies
6pub mod lazy;
7/// Service is a special Component that supports dependency injection at compile time
8pub mod service;
9
10use crate::error::Result;
11use crate::{app::AppBuilder, error::AppError};
12use async_trait::async_trait;
13use component::ComponentRef;
14pub use lazy::LazyComponent;
15use std::{
16    any::{self, Any},
17    ops::Deref,
18    sync::Arc,
19};
20pub use service::Service;
21
22/// Plugin Reference
23#[derive(Clone)]
24pub struct PluginRef(Arc<dyn Plugin>);
25
26/// Defined plugin interface
27#[async_trait]
28pub trait Plugin: Any + Send + Sync {
29    /// Configures the `App` to which this plugin is added.
30    async fn build(&self, _app: &mut AppBuilder) {}
31
32    /// Configures the `App` to which this plugin is added.
33    /// The immediately plugin will not be added to the registry,
34    /// and the plugin cannot obtain components registered in the registry.
35    fn immediately_build(&self, _app: &mut AppBuilder) {}
36
37    /// Configures a name for the [`Plugin`] which is primarily used for checking plugin
38    /// uniqueness and debugging.
39    fn name(&self) -> &str {
40        std::any::type_name::<Self>()
41    }
42
43    /// A list of plugins to depend on. The plugin will be built after the plugins in this list.
44    fn dependencies(&self) -> Vec<&str> {
45        vec![]
46    }
47
48    /// Whether the plugin should be built immediately when added
49    fn immediately(&self) -> bool {
50        false
51    }
52}
53
54impl PluginRef {
55    pub(crate) fn new<T: Plugin>(plugin: T) -> Self {
56        Self(Arc::new(plugin))
57    }
58}
59
60impl Deref for PluginRef {
61    type Target = dyn Plugin;
62
63    fn deref(&self) -> &Self::Target {
64        &*self.0
65    }
66}
67
68/// Component Registry
69pub trait ComponentRegistry {
70    /// Get the component reference of the specified type
71    fn get_component_ref<T>(&self) -> Option<ComponentRef<T>>
72    where
73        T: Any + Send + Sync;
74
75    /// Get the component reference of the specified type.
76    /// If the component does not exist, it will panic.
77    fn get_expect_component_ref<T>(&self) -> ComponentRef<T>
78    where
79        T: Clone + Send + Sync + 'static,
80    {
81        self.get_component_ref().unwrap_or_else(|| {
82            panic!(
83                "{} component not exists in registry",
84                std::any::type_name::<T>()
85            )
86        })
87    }
88
89    /// Get the component reference of the specified type.
90    /// If the component does not exist, it will return AppError::ComponentNotExist.
91    fn try_get_component_ref<T>(&self) -> Result<ComponentRef<T>>
92    where
93        T: Clone + Send + Sync + 'static,
94    {
95        self.get_component_ref()
96            .ok_or_else(|| AppError::ComponentNotExist(std::any::type_name::<T>()))
97    }
98
99    /// Get the component of the specified type
100    fn get_component<T>(&self) -> Option<T>
101    where
102        T: Clone + Send + Sync + 'static;
103
104    /// Get the component of the specified type.
105    /// If the component does not exist, it will panic.
106    fn get_expect_component<T>(&self) -> T
107    where
108        T: Clone + Send + Sync + 'static,
109    {
110        self.get_component().unwrap_or_else(|| {
111            panic!(
112                "{} component not exists in registry",
113                std::any::type_name::<T>()
114            )
115        })
116    }
117
118    /// Get the component of the specified type.
119    /// If the component does not exist, it will return AppError::ComponentNotExist.
120    fn try_get_component<T>(&self) -> Result<T>
121    where
122        T: Clone + Send + Sync + 'static,
123    {
124        self.get_component()
125            .ok_or_else(|| AppError::ComponentNotExist(std::any::type_name::<T>()))
126    }
127
128    /// Is there a component of the specified type in the registry?
129    fn has_component<T>(&self) -> bool
130    where
131        T: Any + Send + Sync;
132}
133
134/// Mutable Component Registry
135pub trait MutableComponentRegistry: ComponentRegistry {
136    /// Add component to the registry
137    fn add_component<C>(&mut self, component: C) -> &mut Self
138    where
139        C: Clone + any::Any + Send + Sync;
140}