use modules::Module; use toml::Table; use std::sync::Arc; use std::sync::mpsc::Receiver; use event::Event; use {Channel, User}; use pvn::Fighter; use pvn::pirates::{Pirate, Pirates}; use pvn::ninjas::{Ninja, Ninjas}; pub struct PvnModule {} impl PvnModule { pub fn new (configuration: &Table) -> Box { Box::new(PvnModule {}) } } fn split_combatants (input: &str) -> Option<(&str, &str)> { let fighters: Vec<&str> = input.split("|").map(|item| item.trim()).collect(); if fighters.len() != 2 { return None; } Option::Some(( *fighters.get(0).expect("should be exactly two fighters"), *fighters.get(1).expect("should be exactly two fighters") )) } 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) } } fn print_pirate (pirate: &Pirate, channel: &Option, user: &User) { reply(&format!("**{}**", pirate.name), channel, user); reply(&format!("Swashbuckling: {}", pirate.swashbuckling), channel, user); reply(&format!("Drunkenness: {}", pirate.drunkenness), channel, user); reply(&format!("Booty: {}", pirate.booty), channel, user); reply(&format!("Weapons: {}", pirate.weapons.join(", ")), channel, user); reply(&format!("**TOTAL POWER: {}**", pirate.power()), channel, user); } fn print_ninja (ninja: &Ninja, channel: &Option, user: &User) { reply(&format!("**{}**", ninja.name), channel, user); reply(&format!("Sneakiness: {}", ninja.sneakiness), channel, user); reply(&format!("Pajamas: {}", ninja.pajamas), channel, user); reply(&format!("Pointy Things: {}", ninja.pointy_things), channel, user); reply(&format!("Weapons: {}", ninja.weapons.join(", ")), channel, user); reply(&format!("**TOTAL POWER: {}**", ninja.power()), channel, user); } fn pirate_vs_ninja (pirate: &Pirate, ninja: &Ninja, channel: &Option, user: &User) { print_pirate(pirate, channel, user); print_ninja(ninja, channel, user); if pirate.power() == ninja.power() { reply("**It's a tie!**", channel, user); } else if pirate.power() > ninja.power() { reply(&format!("**Winner: {}!**", pirate.name), channel, user); } else { reply(&format!("**Winner: {}!**", ninja.name), channel, user); } } struct PirateVsNinja { pirates: Pirates, ninjas: Ninjas } impl PirateVsNinja { fn pvn_command (&mut self, argument: &str, channel: &Option, user: &User) { 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_vs_ninja(pirate, ninja, channel, user); }, Err(error) => { error!("Error getting ninja: {:?}", error); } } }, Err(error) => { error!("Error getting pirate: {:?}", error); } } }, None => { reply("Expected two arguments of the form: {pirate} | {ninja}", channel, user); } } } fn pirate_command (&mut self, name: &str, channel: &Option, user: &User) { match self.pirates.get(name) { Ok(pirate) => { print_pirate(pirate, channel, user); }, Err(error) => { error!("Error getting pirate: {:?}", error); } } } fn ninja_command (&mut self, name: &str, channel: &Option, user: &User) { match self.ninjas.get(name) { Ok(ninja) => { print_ninja(ninja, channel, user); }, Err(error) => { error!("Error getting ninja: {:?}", error); } } } } impl Module for PvnModule { fn consume_events (&self, receiver: Receiver>) { let mut pvn = PirateVsNinja { pirates: Pirates::new(), ninjas: Ninjas::new() }; loop { 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); 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) }, _ => {} } } _ => () } } Err(error) => { error!("Error {:?}", error); } } } } }