diff --git a/src/lib.rs b/src/lib.rs index 8f062ac..2a83cce 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ use std::collections::VecDeque; use irc::proto::{Message, Command::*}; +use regex::Regex; //list of available modules, add mod [MODULE_NAME]; when you complete a new module //is this the best way to do this? probably not @@ -7,24 +8,32 @@ mod modules; use modules::{bully, lenny, join_rude}; -type ModuleFunc = fn(&Message, &VecDeque)->Option<(String, String)>; +type ModuleFunc = fn(regex::Captures, &Message, &VecDeque)->Option<(String, String)>; const NUM_MODS:usize = 2; -const MOD_FUNCS: [ModuleFunc;NUM_MODS] = [lenny::mod_message, bully::mod_message]; -pub fn handle(message: &Message, message_buf: &VecDeque) -> Option<(String,String)> { +const MODULES: [(&str, ModuleFunc);NUM_MODS] = [(lenny::PATTERN, lenny::mod_message), (bully::PATTERN, bully::mod_message)]; - match message.command { - PRIVMSG(_,_) => for function in MOD_FUNCS{ - let response = function(message, message_buf); - if response.is_some() { - return response; +pub fn build_modules() -> Result, regex::Error> { + let mut regex_array: Vec<(Regex, ModuleFunc)> = Vec::with_capacity(NUM_MODS); + for x in 0..MODULES.len() { + let regex = regex::Regex::new(MODULES[x].0)?; + regex_array.push((regex, MODULES[x].1)); + } + Ok(regex_array) +} + +pub fn handle(modules: &Vec<(Regex, ModuleFunc)>, message: &Message, message_buf: &VecDeque) -> Option<(String,String)> { + + match &message.command { + PRIVMSG(_,msg) => for (regex, function) in modules{ + if let Some(captures) = regex.captures(msg.as_str()) { + return function(captures, message, message_buf); } }, JOIN(ref channel,_,_) => return join_rude::join_rude(message.source_nickname().unwrap_or("unknown user"), channel.as_str()), _ => () } - None } diff --git a/src/main.rs b/src/main.rs index 91c6392..8b5ecdf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ use std::collections::VecDeque; use irc::{client::prelude::*, error::Error}; use futures::prelude::*; -use robbit::handle; +use robbit::{build_modules, handle}; #[tokio::main] async fn main() -> Result<(), Error>{ @@ -17,9 +17,10 @@ async fn main() -> Result<(), Error>{ let mut message_buf: VecDeque = VecDeque::with_capacity(max_len); + let module_pair = build_modules().expect("Error building modules"); while let Some(message) = stream.next().await.transpose()? { print!("{}",message); - let response = handle(&message, &message_buf); + let response = handle(&module_pair, &message, &message_buf); if let Some((target,msg))= response { print!("{}",message); diff --git a/src/modules/bully.rs b/src/modules/bully.rs index 13ccd44..e813710 100644 --- a/src/modules/bully.rs +++ b/src/modules/bully.rs @@ -23,22 +23,17 @@ const BULLY_PHRASES:[&str;12] = [ " thinks you were probably the pilot of Ever Given when it clogged the Suez Canal, " ]; -const PATTERN: &str = "^\\$bully (?P[^\\s]+)"; +pub const PATTERN: &str = "^\\$bully (?P[^\\s]+)"; -pub fn mod_message(message: &Message, message_buf: &VecDeque) -> Option<(String,String)> { - let regex: Regex = Regex::new(PATTERN).expect("Error creating regex"); +pub fn mod_message(captures: regex::Captures, message: &Message, _message_buf: &VecDeque) -> Option<(String,String)> { - if let PRIVMSG(_,msg) = message.command.clone() { - if let Some(capture) = regex.captures(msg.as_str()) { - let bully_message: String = BULLY_PHRASES[rand::thread_rng().gen_range(0..BULLY_PHRASES.len())].to_string(); - let to_be_bullied = capture.get(1).unwrap().as_str(); + let bully_message: String = BULLY_PHRASES[rand::thread_rng().gen_range(0..BULLY_PHRASES.len())].to_string(); + let to_be_bullied = captures.get(1).unwrap().as_str(); - let complete_message = message.source_nickname().unwrap_or("unknown_nick").to_string() + bully_message.as_str() + to_be_bullied; + let complete_message = message.source_nickname().unwrap_or("unknown_nick").to_string() + bully_message.as_str() + to_be_bullied; + + Some((message.response_target().unwrap_or("#lug").to_string(), complete_message)) - return Some((message.response_target().unwrap_or("#lug").to_string(), complete_message)); - } - } - None } pub fn usage(message: &Message) -> (String, String) { diff --git a/src/modules/lenny.rs b/src/modules/lenny.rs index 7b97c56..4c8ea74 100644 --- a/src/modules/lenny.rs +++ b/src/modules/lenny.rs @@ -4,26 +4,15 @@ use regex::Regex; use rand::prelude::Rng; const LENNYS:[&str;12] = ["( ͡° ͜ʖ ͡°)","( ͠° ͟ʖ ͡°)","ᕦ( ͡° ͜ʖ ͡°)ᕤ","( ͡° ͜ʖ ͡°)","( ͡~ ͜ʖ ͡°)","( ͡o ͜ʖ ͡o)","͡° ͜ʖ ͡ -","( ͡͡ ° ͜ ʖ ͡ °)","( ͡ ͡° ͡° ʖ ͡° ͡°)","(ง ͠° ͟ل͜ ͡°)ง","( ͡° ͜ʖ ͡ °)","( ͡°╭͜ʖ╮͡° )"]; -const PATTERN: &str = "^\\$[Ll]enny\\s*(?P.*)$"; +pub const PATTERN: &str = "^\\$[Ll]enny\\s*(?P.*)$"; const USAGE: &str = "Usage: ![Ll]enny Displays a Lenny face ( ͡° ͜ʖ ͡°)"; -pub fn mod_message(message: &Message, message_buf: &VecDeque) -> Option<(String,String)> { - let regex: Regex = Regex::new(PATTERN).expect("Error creating regex"); +pub fn mod_message(captures: regex::Captures, message: &Message, message_buf: &VecDeque) -> Option<(String,String)> { + let lenny = LENNYS[rand::thread_rng().gen_range(0..LENNYS.len())].to_string(); + let text = captures.get(1).unwrap().as_str(); - //checks if it was a PRIVMSG - if let PRIVMSG(_,msg) = message.command.clone() { - //checks if it was lenny - if let Some(captures) = regex.captures(msg.as_str()) { - - let lenny = LENNYS[rand::thread_rng().gen_range(0..12)].to_string(); - let text = captures.get(1).unwrap().as_str(); - - return Some((message.response_target().unwrap_or("#lug").to_string(),format!("{} {}", lenny, text))); - } - } - - None + Some((message.response_target().unwrap_or("#lug").to_string(),format!("{} {}", lenny, text))) } pub fn usage(message: &Message) -> (String,String) {