Skip to main content

acts_next/export/
extender.rs

1use crate::{
2    ActError, ActPackageMeta, ActRunAs, DbCollection, Result, env::ActUserVar, scheduler::Runtime,
3    store::DbCollectionIden,
4};
5use core::fmt;
6use std::sync::Arc;
7
8#[derive(Clone)]
9pub struct Extender {
10    runtime: Arc<Runtime>,
11}
12
13impl fmt::Debug for Extender {
14    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15        f.debug_struct("Extender").finish()
16    }
17}
18
19impl Extender {
20    pub(crate) fn new(runtime: &Arc<Runtime>) -> Self {
21        Self {
22            runtime: runtime.clone(),
23        }
24    }
25
26    /// register module
27    ///
28    /// ## Example
29    /// ```no_run
30    /// use acts::Engine;
31    /// mod test_module {
32    ///   use acts::{ActUserVar, Vars, Result};
33    ///   #[derive(Clone)]
34    ///   pub struct TestModule;
35    ///   impl ActUserVar for TestModule {
36    ///     fn name(&self) -> String {
37    ///         "my_var".to_string()
38    ///     }
39    ///
40    ///     fn default_data(&self) -> Option<Vars> {
41    ///         None
42    ///     }
43    ///   }
44    /// }
45    /// let engine = Engine::new().start();
46    /// let module = test_module::TestModule;
47    /// engine.extender().register_var(&module);
48    /// ```
49    pub fn register_var<T: ActUserVar + Clone + 'static>(&self, module: &T) {
50        self.runtime.env().register_var(module)
51    }
52
53    /// register package with meta definition
54    /// ## Example
55    /// ```no_run
56    /// use acts::{ActPackage, ActPackageMeta, Vars};
57    /// use serde::{Deserialize, Serialize};
58    /// use serde_json::json;
59    ///
60    /// #[derive(Debug, Clone, Deserialize, Serialize)]
61    /// pub struct MyPackage {
62    ///    a: i32,
63    ///    b: Vec<String>,
64    /// }
65    /// impl ActPackage for MyPackage {
66    ///     fn meta() -> ActPackageMeta {
67    ///        ActPackageMeta {
68    ///             name: "my_package",
69    ///             desc: "",
70    ///             icon: "",
71    ///             doc: "",
72    ///             version: "0.1.0",
73    ///             schema: json!({
74    ///                 "type": "object",
75    ///                 "properties": {
76    ///                     "a": { "type": "number" },
77    ///                     "b": { "type": "array" }
78    ///                 }
79    ///             }),
80    ///             run_as: acts::ActRunAs::Irq,
81    ///             resources: vec![],
82    ///             catalog: acts::ActPackageCatalog::App,
83    ///        }
84    ///    }
85    ///  }
86    ///
87    ///  #[tokio::main]
88    ///  async fn main() {
89    ///     let engine = acts::Engine::new().start();
90    ///     engine.extender().register_package(&MyPackage::meta());
91    /// }
92    pub fn register_package(&self, meta: &ActPackageMeta) -> Result<()> {
93        if meta.run_as == ActRunAs::Func {
94            return Err(ActError::Package(
95                "package run_as must be one of Irq and Msg".to_string(),
96            ));
97        }
98        let package = meta.into_data()?;
99        self.runtime.cache().store().publish(&package)?;
100
101        Ok(())
102    }
103
104    /// register collection
105    /// ## Example
106    ///
107    /// ```no_run
108    /// use acts::{Engine, Result, DbCollection, data};
109    /// use std::sync::Arc;
110    ///
111    /// pub struct MyCollection;
112    /// impl DbCollection for MyCollection {
113    ///    type Item = data::Event;
114    ///     fn exists(&self, id: &str) -> Result<bool> {
115    ///         Ok(true)
116    ///     }
117    ///     
118    ///     fn find(&self, id: &str) -> Result<Self::Item> {
119    ///         Ok(data::Event {
120    ///             id: todo!(),
121    ///             name: todo!(),
122    ///             mid: todo!(),
123    ///             ver: todo!(),
124    ///             uses: todo!(),
125    ///             params: todo!(),
126    ///             create_time: todo!(),
127    ///             timestamp: todo!(),
128    ///         })
129    ///     }
130    ///     
131    ///     fn query(&self, q: &acts::query::Query) -> Result<acts::PageData<Self::Item>> {
132    ///         Ok(acts::PageData {
133    ///             count: 0,
134    ///             page_num: 0,
135    ///             page_count: 0,
136    ///             page_size: 0,
137    ///             rows: vec![],
138    ///         })
139    ///     }
140    ///     
141    ///     fn create(&self, data: &Self::Item) -> Result<bool> {
142    ///         Ok(true)
143    ///     }
144    ///     
145    ///     fn update(&self, data: &Self::Item) -> Result<bool> {
146    ///         Ok(true)
147    ///     }
148    ///     
149    ///     fn delete(&self, id: &str) -> Result<bool> {
150    ///         Ok(true)
151    ///     }
152    /// }
153    ///
154    ///  #[tokio::main]
155    ///  async fn main() {
156    ///     let engine = acts::Engine::new().start();
157    ///     let collection: Arc<dyn DbCollection<Item = data::Event> + Send + Sync> = Arc::new(MyCollection);
158    ///     engine.extender().register_collection(collection);
159    /// }
160    pub fn register_collection<DATA>(
161        &self,
162        collection: Arc<dyn DbCollection<Item = DATA> + Send + Sync + 'static>,
163    ) where
164        DATA: DbCollectionIden + 'static,
165    {
166        self.runtime.store().register(collection);
167    }
168}