diff --git a/src/event/mod.rs b/src/event/mod.rs index 97bae51..da6914d 100644 --- a/src/event/mod.rs +++ b/src/event/mod.rs @@ -1,7 +1,7 @@ -use {Channel, User}; +use {Message, Channel, User}; pub enum Event { - Message { sender: User, channel: Option, content: String }, + Message { message: Message }, Join { channel: Channel }, Quit { channel: Channel } } diff --git a/src/helpers/command.rs b/src/helpers/command.rs new file mode 100644 index 0000000..e9b75bb --- /dev/null +++ b/src/helpers/command.rs @@ -0,0 +1,6 @@ +pub fn split_command (input: &str) -> Option<(&str, &str)> { + match input.split_whitespace().into_iter().next() { + Some(command) => { Some((command, input[command.len()..].trim())) }, + None => None + } +} diff --git a/src/helpers/mod.rs b/src/helpers/mod.rs index a709fbe..9fe7961 100644 --- a/src/helpers/mod.rs +++ b/src/helpers/mod.rs @@ -1,13 +1 @@ -use event::Event; - -pub fn reply_to (event: Event, reply: &str) { - match event { - Event::Message { content: message, channel, sender } => { - match channel { - Some(channel) => channel.send(reply), - None => sender.send(reply) - } - } - _ => () - } -} +pub mod command; diff --git a/src/lib.rs b/src/lib.rs index 3d2f5f7..fbf0489 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -89,6 +89,21 @@ impl Tenquestionmarks { } } +pub struct Message { + content: String, + author: User, + channel: Option +} + +impl Message { + fn reply (&self, message: &str) { + match self.channel { + Some(ref channel) => channel.send(message), + None => self.author.send(message) + } + } +} + pub struct Channel { name: String, description: String, diff --git a/src/modules/discord.rs b/src/modules/discord.rs index ddb2b08..aeb2c99 100644 --- a/src/modules/discord.rs +++ b/src/modules/discord.rs @@ -10,9 +10,7 @@ use event; use std::sync::Arc; use std::sync::mpsc::Sender; -use MessageSender; -use User; -use Channel; +use {MessageSender, Message, User, Channel}; pub struct DiscordModule { token: String, @@ -82,7 +80,13 @@ impl Module for DiscordModule { }) }; - match sender.send(Arc::new(event::Event::Message { sender: author, content: message.content, channel: Option::Some(channel) })) { + let message = Message { + author: author, + content: message.content, + channel: Some(channel) + }; + + match sender.send(Arc::new(event::Event::Message { message: message })) { Err(err) => error!("Error sending message event: {:?}", err), Ok(_) => {} } diff --git a/src/modules/echo.rs b/src/modules/echo.rs index 9ccaf11..b6d603c 100644 --- a/src/modules/echo.rs +++ b/src/modules/echo.rs @@ -3,6 +3,8 @@ use toml::Table; use std::sync::Arc; use std::sync::mpsc::Receiver; + +use helpers::command::split_command; use event::Event; pub struct EchoModule { @@ -13,7 +15,7 @@ impl EchoModule { pub fn new (configuration: &Table) -> Box { let prefix = configuration.get("prefix") .and_then(|value| value.as_str()) - .unwrap_or("!echo "); + .unwrap_or("!echo"); Box::new(EchoModule { prefix: String::from(prefix) @@ -27,14 +29,15 @@ impl Module for EchoModule { match receiver.recv() { Ok(event) => { match *event { - Event::Message { content: ref message, ref channel, ref sender } => { - debug!("Received message... {:?}", message); - if message.starts_with(self.prefix.as_str()) { - let substring = &message[self.prefix.chars().count()..]; - match *channel { - Some(ref channel) => channel.send(substring), - None => sender.send(substring) - } + Event::Message { ref message } => { + debug!("Received message... {:?}", message.content); + match split_command(&message.content) { + Some((command, argument)) => { + if command == self.prefix { + message.reply(argument); + } + }, + _ => {} } } _ => () diff --git a/src/modules/pvn.rs b/src/modules/pvn.rs index ad05822..8435591 100644 --- a/src/modules/pvn.rs +++ b/src/modules/pvn.rs @@ -5,7 +5,8 @@ use std::sync::Arc; use std::sync::mpsc::Receiver; use event::Event; -use {Channel, User}; +use {Message, Channel, User}; +use helpers::command::split_command; use pvn::Error; use pvn::Fighter; @@ -32,46 +33,32 @@ fn split_combatants (input: &str) -> Option<(&str, &str)> { )) } -fn split_command (input: &str) -> Option<(&str, &str)> { - match input.split_whitespace().into_iter().next() { - Some(command) => { Some((command, input[command.len()..].trim())) }, - None => None - } -} - -fn reply (message: &str, channel: &Option, user: &User) { - match *channel { - Some(ref channel) => channel.send(message), - None => user.send(message) - } -} - trait PvnFighter: Fighter { fn name (&self) -> &str; - fn print (&self, channel: &Option, user: &User); + fn print (&self, message: &Message); - fn fight (&self, other: &PvnFighter, channel: &Option, user: &User) { - self.print(channel, user); - other.print(channel, user); + fn fight (&self, other: &PvnFighter, message: &Message) { + self.print(message); + other.print(message); if self.power() == other.power() { - reply("**It's a tie!**", channel, user); + message.reply("**It's a tie!**"); } else if self.power() > other.power() { - reply(&format!("**Winner: {}!**", self.name()), channel, user); + message.reply(&format!("**Winner: {}!**", self.name())); } else { - reply(&format!("**Winner: {}!**", other.name()), channel, user); + message.reply(&format!("**Winner: {}!**", other.name())); } } } impl PvnFighter for Pirate { - fn print (&self, channel: &Option, user: &User) { - reply(&format!("**{}**", self.name), channel, user); - reply(&format!("Swashbuckling: {}", self.swashbuckling), channel, user); - reply(&format!("Drunkenness: {}", self.drunkenness), channel, user); - reply(&format!("Booty: {}", self.booty), channel, user); - reply(&format!("Weapons: {}", self.weapons.join(", ")), channel, user); - reply(&format!("**TOTAL POWER: {}**", self.power()), channel, user); + fn print (&self, message: &Message) { + message.reply(&format!("**{}**", self.name)); + message.reply(&format!("Swashbuckling: {}", self.swashbuckling)); + message.reply(&format!("Drunkenness: {}", self.drunkenness)); + message.reply(&format!("Booty: {}", self.booty)); + message.reply(&format!("Weapons: {}", self.weapons.join(", "))); + message.reply(&format!("**TOTAL POWER: {}**", self.power())); } fn name (&self) -> &str { @@ -80,13 +67,13 @@ impl PvnFighter for Pirate { } impl PvnFighter for Ninja { - fn print (&self, channel: &Option, user: &User) { - reply(&format!("**{}**", self.name), channel, user); - reply(&format!("Sneakiness: {}", self.sneakiness), channel, user); - reply(&format!("Pajamas: {}", self.pajamas), channel, user); - reply(&format!("Pointy Things: {}", self.pointy_things), channel, user); - reply(&format!("Weapons: {}", self.weapons.join(", ")), channel, user); - reply(&format!("**TOTAL POWER: {}**", self.power()), channel, user); + fn print (&self, message: &Message) { + message.reply(&format!("**{}**", self.name)); + message.reply(&format!("Sneakiness: {}", self.sneakiness)); + message.reply(&format!("Pajamas: {}", self.pajamas)); + message.reply(&format!("Pointy Things: {}", self.pointy_things)); + message.reply(&format!("Weapons: {}", self.weapons.join(", "))); + message.reply(&format!("**TOTAL POWER: {}**", self.power())); } fn name (&self) -> &str { @@ -100,14 +87,14 @@ struct PirateVsNinja { } impl PirateVsNinja { - fn pvn_command (&mut self, argument: &str, channel: &Option, user: &User) { + fn pvn_command (&mut self, argument: &str, message: &Message) { match split_combatants(argument) { Some((pirate_name, ninja_name)) => { match self.pirates.get(pirate_name) { Ok(pirate) => { match self.ninjas.get(ninja_name) { Ok(ninja) => { - pirate.fight(ninja, channel, user); + pirate.fight(ninja, message); }, Err(error) => { error!("Error getting ninja: {:?}", error); @@ -120,15 +107,15 @@ impl PirateVsNinja { } }, None => { - reply("Expected two arguments of the form: {pirate} | {ninja}", channel, user); + message.reply("Expected two arguments of the form: {pirate} | {ninja}"); } } } - fn pirate_command (&mut self, name: &str, channel: &Option, user: &User) { + fn pirate_command (&mut self, name: &str, message: &Message) { match self.pirates.get(name) { Ok(pirate) => { - pirate.print(channel, user); + pirate.print(message); }, Err(error) => { error!("Error getting pirate: {:?}", error); @@ -136,10 +123,10 @@ impl PirateVsNinja { } } - fn ninja_command (&mut self, name: &str, channel: &Option, user: &User) { + fn ninja_command (&mut self, name: &str, message: &Message) { match self.ninjas.get(name) { Ok(ninja) => { - ninja.print(channel, user); + ninja.print(message); }, Err(error) => { error!("Error getting ninja: {:?}", error); @@ -167,13 +154,13 @@ impl Module for PvnModule { match receiver.recv() { Ok(event) => { match *event { - Event::Message { content: ref message, ref channel, ref sender } => { - let command = split_command(message); - debug!("Received message... {:?}", message); + Event::Message { ref message } => { + let command = split_command(&message.content); + debug!("Received message... {:?}", &message.content); match command { - Some(("?pvn", argument)) => { pvn.pvn_command(argument, channel, sender) }, - Some(("?pirate", name)) => { pvn.pirate_command(name, channel, sender) }, - Some(("?ninja", name)) => { pvn.ninja_command(name, channel, sender) }, + Some(("?pvn", argument)) => { pvn.pvn_command(argument, message) }, + Some(("?pirate", name)) => { pvn.pirate_command(name, message) }, + Some(("?ninja", name)) => { pvn.ninja_command(name, message) }, _ => {} } } diff --git a/src/modules/random.rs b/src/modules/random.rs index a6e1f89..7acb3f3 100644 --- a/src/modules/random.rs +++ b/src/modules/random.rs @@ -3,8 +3,9 @@ use toml::Table; use std::sync::Arc; use std::sync::mpsc::Receiver; -use event::Event; +use helpers::command::split_command; +use event::Event; use rand; pub struct RandomModule { @@ -41,15 +42,16 @@ impl Module for RandomModule { match receiver.recv() { Ok(event) => { match *event { - Event::Message { content: ref message, ref channel, ref sender } => { - debug!("Received message... {:?}", message); - if message.starts_with(self.prefix.as_str()) { - let response = &rand::sample(&mut rng, &self.responses, 1)[0][..]; - - match *channel { - Some(ref channel) => channel.send(response), - None => sender.send(response) - } + Event::Message { ref message } => { + debug!("Received message... {:?}", message.content); + match split_command(&message.content) { + Some((command, _)) => { + if command == self.prefix { + let response = &rand::sample(&mut rng, &self.responses, 1)[0][..]; + message.reply(response); + } + }, + _ => {} } } _ => () diff --git a/src/modules/stdin.rs b/src/modules/stdin.rs index 11f65cf..374649a 100644 --- a/src/modules/stdin.rs +++ b/src/modules/stdin.rs @@ -3,8 +3,7 @@ use std::io; use modules::Module; use toml::Table; -use User; -use MessageSender; +use {MessageSender, Message, User}; use std::sync::Arc; use std::sync::mpsc::Sender; @@ -35,8 +34,8 @@ impl Module for StdinModule { let mut input = String::new(); match io::stdin().read_line(&mut input) { Ok(n) => { - let message = Event::Message { - sender: User { + let message = Message { + author: User { name: String::from("Dave"), sender: Box::new(StdinMessageSender { name: String::from("Dave") @@ -46,7 +45,7 @@ impl Module for StdinModule { channel: None }; - match sender.send(Arc::new(message)) { + match sender.send(Arc::new(Event::Message { message: message })) { Err(err) => error!("Error sending message event: {:?}", err), Ok(_) => {} }