Skip to main content

acts_next/
builder.rs

1#[cfg(test)]
2use crate::config::ConfigData;
3use crate::{ActPlugin, Config, Engine, Result, config::ConfigLog};
4use std::path::Path;
5
6pub struct EngineBuilder {
7    config: Config,
8    plugins: Vec<Box<dyn ActPlugin>>,
9}
10
11impl Default for EngineBuilder {
12    fn default() -> Self {
13        Self::new()
14    }
15}
16
17impl EngineBuilder {
18    pub fn new() -> Self {
19        let mut config = Config::default();
20        #[cfg(not(test))]
21        let file = Path::new("config/acts.toml");
22
23        #[cfg(test)]
24        let file = Path::new("test/acts.toml");
25
26        if file.exists() {
27            config = Config::create(file);
28        }
29
30        Self {
31            config,
32            plugins: Vec::new(),
33        }
34    }
35
36    #[cfg(test)]
37    pub fn set_config(mut self, data: &ConfigData) -> Self {
38        self.config = Config {
39            data: data.clone(),
40            table: toml::Table::new(),
41        };
42        self
43    }
44
45    pub fn set_config_source(mut self, source: &Path) -> Self {
46        self.config = Config::create(source);
47        self
48    }
49
50    pub fn log(mut self, dir: &str, level: &str) -> Self {
51        self.config.data.log = Some(ConfigLog {
52            dir: dir.to_string(),
53            level: level.to_string(),
54        });
55        self
56    }
57
58    pub fn cache_size(mut self, size: i64) -> Self {
59        self.config.data.cache_cap = Some(size);
60        self
61    }
62
63    pub fn tick_interval_secs(mut self, secs: i64) -> Self {
64        self.config.data.tick_interval_secs = Some(secs);
65        self
66    }
67
68    pub fn max_message_retry_times(mut self, retry_times: i32) -> Self {
69        self.config.data.max_message_retry_times = Some(retry_times);
70        self
71    }
72
73    /// register plugin
74    ///
75    /// ## Example
76    ///
77    /// ```no_run
78    /// use acts::{ActPlugin, Message, Engine, EngineBuilder, Workflow, Result};
79    ///
80    /// #[derive(Clone)]
81    /// struct TestPlugin;
82    /// impl TestPlugin {
83    ///     fn new() -> Self {
84    ///         Self
85    ///     }
86    /// }
87    /// #[async_trait::async_trait]
88    /// impl ActPlugin for TestPlugin {
89    ///     async fn on_init(&self, engine: &Engine) -> Result<()> {
90    ///         println!("TestPlugin");
91    ///         engine.channel().on_start(|e| {});
92    ///         engine.channel().on_complete(|e| {});
93    ///         engine.channel().on_message(|e| {});
94    ///         Ok(())       
95    ///     }
96    /// }
97    ///
98    /// #[tokio::main]
99    /// async fn main() {
100    ///     let engine = EngineBuilder::new().add_plugin(&TestPlugin::new()).build().await.unwrap().start();
101    /// }
102    /// ```
103    pub fn add_plugin<T>(mut self, plugin: &T) -> Self
104    where
105        T: ActPlugin + Clone + 'static,
106    {
107        self.plugins.push(Box::new(plugin.clone()));
108        self
109    }
110
111    pub async fn build(&self) -> Result<Engine> {
112        let engine = Engine::new_with_config(&self.config);
113
114        // init the cache store to make sure the plugin can registry package to the store
115        engine.runtime().cache().init(&engine);
116
117        // init plugins
118        for plugin in self.plugins.iter() {
119            plugin.on_init(&engine).await?;
120        }
121
122        Ok(engine)
123    }
124}