use std::error::Error; use std::collections::HashMap; /* ModulesManager is made of modulesdb , a HashMap of BotModules with a Vector representing their enabled/disabled status based on channel and instance Example { BotModule("Experiments") , [Enabled(Channel("modulatingforce")) , Disabled(Channel("modulatingforce")), Enabled(Instance)] } */ #[derive(Debug, PartialEq, Eq, Hash)] pub enum ModType { BotModule(String), } pub use ModType::BotModule; #[derive(Debug, PartialEq, Eq, Hash)] pub enum ChType { Channel(String), } pub use ChType::Channel; #[derive(Debug)] enum StatusLvl { Instance, Ch(ChType), } #[derive(Debug)] pub enum ModStatusType { Enabled(StatusLvl), Disabled(StatusLvl), } // pub use EnType::Enabled; #[derive(Debug)] enum BotAction { C(BotCommand), L(Listener), R(Routine), } #[derive(Debug)] struct BotCommand {} #[derive(Debug)] struct Listener { module : ModType, name : String, // exec_body : fn, help : String } #[derive(Debug)] struct Routine {} #[derive(Debug)] pub struct ModulesManager { statusdb: HashMap>, botactions: HashMap>, } impl ModulesManager { pub fn init() -> ModulesManager { // initializes the modulers manager // Ideally, this should have added known modules based on // directory structure and API user recommendations let mut m = HashMap::new(); let mut act = HashMap::new(); // -- some processing including adding into the hashmap // let newmodule = BotModule(String::from("GambaCore")); let newlistener = Listener { module : BotModule(String::from("experiments").to_owned()), name : String::from("socklistener"), help : String::from("This will listen and react to sock randomly"), }; // As a Demonstration, the listener's Module is added and Enabled at Instance level let statusvector = m .entry(BotModule(String::from("experiments"))) .or_insert(Vec::new()); statusvector.push(ModStatusType::Enabled(StatusLvl::Instance)); let modactions = act .entry( BotModule(String::from("experiments"))) .or_insert(Vec::new()); modactions.push(BotAction::L(newlistener)); let mgr = ModulesManager { statusdb : m, botactions : act, }; println!(">> Modules Manager : {:?}",mgr); mgr } pub fn modstatus(&self, _:ModType, _:ChType) -> ModStatusType { // Example usage : botmanager.modstatus( // BotModule("GambaCore"), // Channel("modulatingforce") // ) // - The ModStatusType checks in the context of the given channel , // but also validates based on wheher the module is disabled at a bot instance // level as well ModStatusType::Enabled(StatusLvl::Instance) } pub fn togglestatus(&self, _:ModType, _:ChType) -> ModStatusType { // enables or disables based on current status ModStatusType::Enabled(StatusLvl::Instance) } pub fn setstatus(&self, _:ModType, _:ModStatusType) -> Result<&str,Box> { // sets the status based given ModSatusType // e.g., b.setstatus(BodModule("GambaCore"), Enabled(Channel("modulatingforce"))).expect("ERROR") Ok("") } fn statuscleanup(&self,chnl:Option) -> () { // internal cleans up statusdb . For example : // - remove redudancies . If we see several Enabled("m"), only keep 1x // - Clarify Conflict. If we see Enabled("m") and Disabled("m") , we remove Enabled("m") and keep Disabled("m") // the IDEAL is that this is ran before every read/update operation to ensure quality // Option can pass Some(Channel("m")) (as an example) so statuscleanup only works on the given channel // Passing None to chnl may be a heavy operation, as this will review and look at the whole table () } }