rs-eda 0.1.5

rust EDA event-driven framework
Documentation
use crate::{
    event::EventDispatcher,
    plugin::PluginOptions,
    strategy::StrategyOptions,
    units::error::{BError, MyError},
};
use serde_json::Value;
use std::collections::HashMap;

type PluginsMap = HashMap<String, Box<dyn PluginOptions>>;
type StrategysMap = HashMap<String, Box<dyn StrategyOptions>>;

pub struct Engine {
    pub event: EventDispatcher,
    plugins: PluginsMap,
    strategys: StrategysMap,
}

impl Engine {
    pub fn new() -> Self {
        Self {
            event: EventDispatcher::new(),
            plugins: HashMap::new(),
            strategys: HashMap::new(),
        }
    }
    // 获取插件列表
    pub fn get_plugins(&self) -> &PluginsMap {
        &self.plugins
    }
    // 获取指定插件数据
    pub fn plugin_data(&self, name: &str) -> Option<Value> {
        if let Some(x) = self.plugins.get(name) {
            x.get_data()
        } else {
            println!("插件{}不存在", name);
            None
        }
    }
    // 获取策略列表
    pub fn get_strategys(&self) -> &StrategysMap {
        &self.strategys
    }
    // 获取指定策略数据
    pub fn strategy_data(&self, name: &str) -> Option<Value> {
        if let Some(x) = self.strategys.get(name) {
            x.get_data()
        } else {
            println!("策略{}不存在", name);
            None
        }
    }
    // 安装插件
    pub fn install<P: PluginOptions + 'static>(&mut self, plugin: P) -> MyError<()> {
        let name = plugin.name();
        if !self.plugins.contains_key(name) {
            // 不存在对应的插件

            // 检查插件依赖
            let mut deps: Vec<&str> = Vec::new();
            for dep in plugin.deps() {
                // 依赖插件不存在
                if !self.plugins.contains_key(dep) {
                    deps.push(dep);
                }
            }
            if !deps.is_empty() {
                // 提示错误
                return Err(BError::with_msg(&format!(
                    "安装插件 '{}' 出错:依赖插件 '{}' 不存在",
                    name,
                    deps.join(",")
                )));
            }

            // 执行插件安装方法
            let mut plugin_box = Box::new(plugin);
            plugin_box.install(self);

            // 记录插件
            self.plugins
                .insert(plugin_box.name().to_string(), plugin_box);
        }
        Ok(())
    }
    // 卸载插件
    pub fn uninstall(&mut self, plugin_name: &str) {
        if let Some(mut plugin) = self.plugins.remove(plugin_name) {
            // 策略B依赖插件A,插件A被卸载,关联的策略B也要被回滚
            let mut strategies = Vec::new();
            for (_, strategy) in self.strategys.iter() {
                if strategy.condition().contains(&plugin_name) {
                    strategies.push(strategy.name().to_string());
                }
            }
            // 执行回滚操作
            for strategy_name in strategies {
                self.rollback(&strategy_name);
            }

            // 插件B依赖插件A,插件A被卸载,关联的插件B也要被卸载
            let mut plugins = Vec::new();
            for (_, plugin) in self.plugins.iter() {
                if plugin.deps().contains(&plugin_name) {
                    plugins.push(plugin.name().to_string());
                }
            }
            // 执行关键插件的卸载
            for plugin_name in plugins {
                self.uninstall(&plugin_name);
            }

            // 执行销毁方法
            plugin.dispose(self);
        } else {
            println!("插件 {} 不存在", plugin_name)
        }
    }
    // 执行策略
    pub fn exec<S: StrategyOptions + 'static>(&mut self, strategy: S) -> MyError<()> {
        let name = strategy.name();
        if !self.strategys.contains_key(name) {
            // 不存在对应的策略

            // 检查策略依赖
            let mut plugins: Vec<&str> = Vec::new();
            for plugin in strategy.condition() {
                // 依赖插件不存在,记录起来
                if !self.plugins.contains_key(plugin) {
                    plugins.push(plugin);
                }
            }
            if plugins.len() > 0 {
                // 提示错误
                return Err(BError::with_msg(&format!(
                    "执行策略 '{}' 出错:依赖插件 '{}' 不存在",
                    name,
                    plugins.join(",")
                )));
            }

            // 执行策略
            strategy.exec(self);

            // 记录策略
            self.strategys
                .insert(strategy.name().to_string(), Box::new(strategy));
        }

        Ok(())
    }
    // 回滚策略
    pub fn rollback(&mut self, strategy_name: &str) {
        // 找到与name对应的策略并删除
        if let Some(mut strategy) = self.strategys.remove(strategy_name) {
            // 执行回滚方法
            strategy.rollback(self);
        } else {
            println!("策略 {} 不存在", strategy_name)
        }
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_fun() {}
}