diff options
| -rw-r--r-- | src/lib.rs | 4 | ||||
| -rw-r--r-- | src/plugins/currency.rs | 165 | ||||
| -rw-r--r-- | src/plugins/emoji.rs | 58 | ||||
| -rw-r--r-- | src/plugins/mod.rs | 1 |
4 files changed, 198 insertions, 30 deletions
@@ -16,7 +16,9 @@ pub fn run() { let server = IrcServer::new("config.toml").unwrap(); server.identify().unwrap(); - let plugins: Vec<Arc<Mutex<Plugin>>> = vec![Arc::new(Mutex::new(plugins::emoji::Emoji::new()))]; + let plugins: Vec<Arc<Mutex<Plugin>>> = + vec![Arc::new(Mutex::new(plugins::emoji::Emoji::new())), + Arc::new(Mutex::new(plugins::currency::Currency::new()))]; server .for_each_incoming(|message| { diff --git a/src/plugins/currency.rs b/src/plugins/currency.rs new file mode 100644 index 0000000..71b943a --- /dev/null +++ b/src/plugins/currency.rs @@ -0,0 +1,165 @@ +extern crate reqwest; +extern crate serde; +extern crate serde_json; +extern crate regex; + +use std::io::Read; +use irc::client::prelude::*; +use irc::error::Error as IrcError; +use self::regex::Regex; +use plugin::Plugin; +use self::reqwest::Client; +use self::reqwest::header::Connection; +use self::serde_json::Value; + +register_plugin!(Currency); + +lazy_static! { + static ref RE: Regex = Regex::new(r"([0-9]+) ([A-Za-z]+) (?i)(to) ([A-Za-z]+)").unwrap(); +} + +struct ConvertionRequest<'a> { + value: f64, + source: &'a str, + target: &'a str, +} + +macro_rules! try_option { + ($e:expr) => { + match $e { + Some(v) => v, + None => { return None; } + } + } +} + +impl<'a> ConvertionRequest<'a> { + fn send(&self) -> Option<f64> { + + let response = Client::new() + .get("https://api.fixer.io/latest") + .form(&[("base", self.source)]) + .header(Connection::close()) + .send(); + + match response { + Ok(mut response) => { + let mut body = String::new(); + try_option!(response.read_to_string(&mut body).ok()); + println!("{}", body); + + let convertion_rates: Result<Value, _> = serde_json::from_str(&body); + match convertion_rates { + Ok(convertion_rates) => { + + let rates: &Value = try_option!(convertion_rates.get("rates")); + let target_rate: &Value = try_option!(rates.get(self.target.to_uppercase())); + Some(self.value * try_option!(target_rate.as_f64())) + } + Err(_) => None, + } + } + Err(_) => None, + } + } +} + +impl Currency { + fn grep_request<'a>(&self, msg: &'a str) -> Option<ConvertionRequest<'a>> { + match RE.captures(msg) { + Some(captures) => { + Some(ConvertionRequest { + value: { + let capture = try_option!(captures.get(1)).as_str(); + try_option!(capture.parse().ok()) + }, + source: try_option!(captures.get(2)).as_str(), + target: try_option!(captures.get(4)).as_str(), // 3 is to/TO + }) + } + None => None, + } + } + + fn convert(&self, + server: &IrcServer, + _: &Message, + target: &str, + msg: &str) + -> Result<(), IrcError> { + let request = match self.grep_request(msg) { + Some(request) => request, + None => { + return Ok(()); + } + }; + + match request.send() { + Some(response) => { + server.send_privmsg(target, + &*format!("{} {} => {:.4} {}", + request.value, + request.source, + response / 1.00000000, + request.target)) + } + None => server.send_privmsg(target, "Error while converting given currency"), + } + } +} + +impl Plugin for Currency { + fn is_allowed(&self, _: &IrcServer, message: &Message) -> bool { + match message.command { + Command::PRIVMSG(_, ref msg) => RE.is_match(msg), + _ => false, + } + } + + fn execute(&mut self, server: &IrcServer, message: &Message) -> Result<(), IrcError> { + match message.command { + Command::PRIVMSG(ref target, ref msg) => self.convert(server, message, target, msg), + _ => Ok(()), + } + } +} + +#[cfg(test)] +mod tests { + use tests::{make_server, get_server_value}; + + use irc::client::prelude::*; + + use plugin::Plugin; + use regex::Regex; + use super::Currency; + + #[test] + fn test_big_jpy_to_eur() { + let server = make_server("PRIVMSG test :5000000 JPY to EUR\r\n"); + let mut plugin = Currency::new(); + + for message in server.iter() { + let message = message.unwrap(); + assert!(plugin.is_allowed(&server, &message)); + assert!(plugin.execute(&server, &message).is_ok()); + } + + let regex = Regex::new(r"=> ([0-9]{2})").unwrap(); + let msg = get_server_value(&server); + let captures = regex.captures(&*msg).unwrap(); + assert!(captures.at(0).is_some()); + + let result = captures + .at(0) + .unwrap() + .split_whitespace() + .last() + .unwrap() + .parse::<i32>(); + assert!(result.is_ok()); + + let value = result.unwrap(); + assert!(value > 10 && value < 100); + } +} diff --git a/src/plugins/emoji.rs b/src/plugins/emoji.rs index 75fc863..6c24584 100644 --- a/src/plugins/emoji.rs +++ b/src/plugins/emoji.rs @@ -66,33 +66,33 @@ impl Plugin for Emoji { #[cfg(test)] mod tests { -// use ::tests::{make_server, get_server_value}; -// -// use irc::client::prelude::*; -// -// use plugin::Plugin; -// use super::Emoji; -// -// #[test] -// fn emoji_message() { -// let server = make_server("PRIVMSG test :emoji\r\n"); -// let mut plugin = Emoji::new(); -// -// server.for_each_incoming(|message| { -// assert!(plugin.execute(&server, &message).is_ok()); -// }).unwrap(); -// -// assert_eq!("PRIVMSG test :emoji name\r\n", &*get_server_value(&server)); -// } -// -// #[test] -// fn no_emoji_message() { -// let server = make_server("PRIVMSG test :test\r\n"); -// let mut plugin = Emoji::new(); -// -// server.for_each_incoming(|message| { -// assert!(plugin.execute(&server, &message).is_ok()); -// }).unwrap(); -// assert_eq!("", &*get_server_value(&server)); -// } + //use ::tests::{make_server, get_server_value}; + // + //use irc::client::prelude::*; + // + //use plugin::Plugin; + //use super::Emoji; + // + //#[test] + //fn emoji_message() { + // let server = make_server("PRIVMSG test :emoji\r\n"); + // let mut plugin = Emoji::new(); + // + // server.for_each_incoming(|message| { + // assert!(plugin.execute(&server, &message).is_ok()); + // }).unwrap(); + // + // assert_eq!("PRIVMSG test :emoji name\r\n", &*get_server_value(&server)); + //} + // + //#[test] + //fn no_emoji_message() { + // let server = make_server("PRIVMSG test :test\r\n"); + // let mut plugin = Emoji::new(); + // + // server.for_each_incoming(|message| { + // assert!(plugin.execute(&server, &message).is_ok()); + // }).unwrap(); + // assert_eq!("", &*get_server_value(&server)); + //} } diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs index 35cdb27..adf54b2 100644 --- a/src/plugins/mod.rs +++ b/src/plugins/mod.rs @@ -1 +1,2 @@ pub mod emoji; +pub mod currency; |
