diff --git a/config.toml b/config.toml index a2b3211..b7dda96 100644 --- a/config.toml +++ b/config.toml @@ -1,9 +1,9 @@ secret = "your login secret" +prefix = ">" [[command]] -# The prefix (a constant in the source code) -# does not need to be specified here. -# It is added automatically. +# The prefix does not need to be added here. +# That is done automatically. trigger = "create_file" # Spaces are not escaped here command = "touch /tmp/test-rce" diff --git a/src/commands.rs b/src/commands.rs index 030e6aa..aa736a3 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -1,9 +1,9 @@ -use super::config::CONFIG; +use super::config::*; use cmd_lib::{CmdResult, Process}; use serde::Deserialize; use serenity::model::channel::Message; -#[derive(Deserialize, Debug)] +#[derive(Deserialize, Debug, PartialEq, Clone)] pub struct Command { trigger: String, command: String, @@ -14,8 +14,10 @@ pub fn print_commands() { CONFIG.commands.iter().for_each(|c| println!("{:?}", c)); } -pub fn find_matching(message: &str) -> Option<&Command> { - CONFIG.commands.iter().find(|&c| message[1..] == c.trigger) +pub fn find_matching<'a>(message: &str, cfg: &'a Config) -> Option<&'a Command> { + cfg.commands + .iter() + .find(|&c| message[cfg.prefix.len()..] == c.trigger) } impl Command { @@ -33,4 +35,12 @@ impl Command { .wait::() .map_err(|e| format!("{:?}", e)) } + + pub fn new(command: &str, trigger: &str, users: Vec) -> Self { + Self { + command: String::from(command), + trigger: String::from(trigger), + users, + } + } } diff --git a/src/config.rs b/src/config.rs index e434881..2ad6985 100644 --- a/src/config.rs +++ b/src/config.rs @@ -11,6 +11,7 @@ pub struct Config { #[serde(rename = "command")] pub commands: Vec, pub secret: String, + pub prefix: String, } lazy_static! { diff --git a/src/main.rs b/src/main.rs index 42b4bcd..057412a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ #[macro_use] extern crate lazy_static; use commands::*; +use config::CONFIG; use serenity::model::channel::Message; use serenity::model::id::ChannelId; use serenity::prelude::*; @@ -15,18 +16,16 @@ pub fn main() { .expect("Could not connect to discord"); } -const PREFIX: char = '>'; - pub struct Handler; impl EventHandler for Handler { fn message(&self, ctx: Context, msg: Message) { - if !msg.content.starts_with(PREFIX) { + if !msg.content.starts_with(&CONFIG.prefix) { return; } - if let Some(command) = find_matching(&msg.content) { + if let Some(command) = find_matching(&msg.content, &CONFIG) { let response = match command.execute(&msg) { Err(e) => e, - Ok(()) => "Done".to_owned(), + Ok(()) => String::from("Done."), }; send(msg.channel_id, &response, &ctx); } @@ -38,3 +37,29 @@ pub fn send(target: ChannelId, message: &str, ctx: &Context) { println!("Could not send message: {}", cause); } } + +#[cfg(test)] +mod tests { + use super::commands::*; + use super::config::*; + use super::*; + + #[test] + fn find_matching_test() { + let cmd = Command::new("ls -l", "show_files", vec![1234567890]); + let cfg = Config { + prefix: String::from(">"), + secret: String::from("1qay2wsx3edc45fv"), + commands: vec![cmd.clone()], + }; + assert_eq!(find_matching(&">show_files", &cfg), Some(&cmd)); + assert_eq!(find_matching(&">show something else", &cfg), None); + + let cfg = Config { + prefix: String::from("!!"), + ..cfg + }; + assert_eq!(find_matching(&">show_files", &cfg), None); + assert_eq!(find_matching(&"!!show_files", &cfg), Some(&cmd)); + } +}