Enh BotCommand & AddBotAction

This commit is contained in:
ModulatingForce 2023-12-21 20:11:32 -05:00
parent 0f805bd1a8
commit 68f08a6e78

View file

@ -1,3 +1,4 @@
use core::{panic};
use std::error::Error; use std::error::Error;
use std::collections::HashMap; use std::collections::HashMap;
@ -29,6 +30,8 @@ pub enum ChType {
pub use ChType::Channel; pub use ChType::Channel;
use crate::core::botinstance::{self, BotInstance};
#[derive(Debug)] #[derive(Debug)]
enum StatusLvl { enum StatusLvl {
@ -51,7 +54,14 @@ pub enum BotAction {
R(Routine), R(Routine),
} }
#[derive(Debug)] #[derive(Debug)]
struct BotCommand {} struct BotCommand {
module : ModType,
command : String, // command call name
alias : Vec<String>, // String of alternative names
// bot_prefix : char, // although should be global?
// exec_body : fn,
help : String,
}
#[derive(Debug)] #[derive(Debug)]
struct Listener { struct Listener {
@ -107,11 +117,37 @@ impl ModulesManager {
// modactions.push(BotAction::L(newlistener)); // modactions.push(BotAction::L(newlistener));
let mgr = ModulesManager { let mut mgr = ModulesManager {
statusdb : m, statusdb : m,
botactions : act, botactions : act,
}; };
// // -- This area can be where bot actions are imported to the bot's module manager
// // -- Below can be used to validate what occurs when dup BotCommands are added
// let bcmd = BotCommand {
// module : BotModule(String::from("experiments 001")),
// command : String::from("DUPCMD1"), // command call name
// alias : vec![String::from("DUPALIAS1A"),String::from("DUPALIAS1B")], // String of alternative names
// // bot_prefix : char, // although should be global?
// // exec_body : fn,
// help : String::from("DUPCMD1 tester"),
// };
// mgr.add_botaction(BotModule(String::from("experiments 001")), BotAction::C(bcmd));
// let bcmd = BotCommand {
// module : BotModule(String::from("experiments 002")),
// command : String::from("DUPCMD2"), // command call name
// alias : vec![String::from("DUPALIAS2A"),String::from("DUPALIAS2B")], // String of alternative names
// // bot_prefix : char, // although should be global?
// // exec_body : fn,
// help : String::from("DUPCMD2 tester"),
// };
// mgr.add_botaction(BotModule(String::from("experiments 002")), BotAction::C(bcmd));
println!(">> Modules Manager : {:?}",mgr); println!(">> Modules Manager : {:?}",mgr);
@ -144,39 +180,141 @@ impl ModulesManager {
} }
pub fn add_botaction(&mut self, in_module:ModType, _:BotAction ) -> () { pub fn add_botaction(&mut self, in_module:ModType, in_action:BotAction ) -> () {
// adds a BotAction to the Modules Manager - This will require a BotModule passed as well /*
// This will including the logic of a valid add adds a BotAction to the Modules Manager - This will require a BotModule passed as well
// If it fails to add, either a PANIC or some default coded business rules that handles the botaction add This will including the logic of a valid add
// For example, this Should PANIC (ideally Panic?) if it does not successfully add a bot module If it fails to add, either a PANIC or some default coded business rules that handles the botaction add
// -- Being unable to indicates a Programming/Developer code logic issue : They cannot add botactions that already exists (?) For example, this Should PANIC (ideally Panic?) if it does not successfully add a bot module
// -- In particular to BotCommands, which must have Unique command call names and aliases that to not conflict with any other -- Being unable to indicates a Programming/Developer code logic issue : They cannot add botactions that already exists (?)
// already BotCommand added name or alias -- In particular to BotCommands, which must have Unique command call names and aliases that to not conflict with any other
// Other types might be fine? For example, if 2 modules have their own listeners but each have the name "targetchatter" , already BotCommand added name or alias
// both would be called separately, even if they both have the same or different logic Other types might be fine? For example, if 2 modules have their own listeners but each have the name "targetchatter" ,
both would be called separately, even if they both have the same or different logic
*/
let newlistener = Listener { // let newlistener = Listener {
// module : BotModule(String::from("experiments").to_owned()), // // module : BotModule(String::from("experiments").to_owned()),
module : in_module.clone(), // module : in_module.clone(),
name : String::from("socklistener"), // name : String::from("socklistener"),
help : String::from("This will listen and react to sock randomly"), // 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 // As a Demonstration, the listener's Module is added and Enabled at Instance level
// [x] Before Adding, validate the following :
// - If BotAction to Add is a BotCommand , In Module Manager DB (botactions),
// Check All Other BotAction Command Names & Aliases to ensure they don't conflict
fn find_conflict_module(mgr:& ModulesManager, act:& BotAction) -> Option<ModType> {
// Some(BotModule(String::from("GambaCore")))
// match act {
// BotAction::C(c) => {
// Some(BotModule(String::from("GambaCore")))
// },
// BotAction::L(l) => None,
// BotAction::R(r) => None,
// }
if let BotAction::C(incmd) = act {
// let n = & mgr.botactions;
let d = &mgr.botactions;
for (module,moduleactions) in d {
for modact in moduleactions.iter() {
if let BotAction::C(dbcmd) = &modact {
// At this point, there is an command incmd and looked up dbcmd
// [x] check if given botcommand c.command:String conflicts with any in botactions
if incmd.command.to_lowercase() == dbcmd.command.to_lowercase() {
// Returning State - with the identified module
// return Some((module.clone(),BotAction::C(*dbcmd.clone())));
// return Some(incmd); // for some reason I keep getting issues
//return Some(BotModule(String::from("GambaCore"))); // works
return Some(module.clone()); // works
// return Some(dbcmd.clone());
}
for a in &dbcmd.alias {
if incmd.command.to_lowercase() == a.to_lowercase() {
// Returning State - with the identified module
// return Some((module.clone(),BotAction::C(dbcmd)));
return Some(module.clone()); // works
}
}
// [x] Then do the same check except for each c.alias
for inalias in &incmd.alias {
if inalias.to_lowercase() == dbcmd.command.to_lowercase() {
// Returning State - with the identified module
// return Some((module.clone(),BotAction::C(dbcmd)));
return Some(module.clone()); // works
}
for a in &dbcmd.alias {
if inalias.to_lowercase() == a.to_lowercase() {
// Returning State - with the identified module
// return Some((module.clone(),BotAction::C(dbcmd)));
return Some(module.clone()); // works
}
}
}
}
}
}
// return Some(BotModule(String::from("GambaCore")))
}
// for all other scenarios (e.g., Listener, Routine), find no conflicts
None
}
// if let probmod = find_conflict_module(&self, &in_action) {
// // () // return because there was a conflict?
// panic!("ERROR: Could not add {:?} ; there was a conflict with existing module {:?}", in_action , probmod );
// }
match find_conflict_module(&self, &in_action) {
Some(c) => panic!("ERROR: Could not add {:?} ; there was a conflict with existing module {:?}", in_action , c ),
None => (),
}
let statusvector = self.statusdb let statusvector = self.statusdb
// .entry(BotModule(String::from("experiments"))) // .entry(BotModule(String::from("experiments")))
.entry(in_module.clone()) .entry(in_module.clone())
.or_insert(Vec::new()); .or_insert(Vec::new());
statusvector.push(ModStatusType::Enabled(StatusLvl::Instance)); statusvector.push(ModStatusType::Enabled(StatusLvl::Instance)); // Pushes the Module as Enabled at Instance Level
let modactions = self.botactions let modactions = self.botactions
//.entry( BotModule(String::from("experiments"))) //.entry( BotModule(String::from("experiments")))
.entry( in_module.clone()) .entry( in_module.clone())
.or_insert(Vec::new()); .or_insert(Vec::new());
modactions.push(BotAction::L(newlistener)); // modactions.push(BotAction::L(newlistener));
modactions.push(in_action);
(); ();
} }