pacbot/src/commands/mod.rs
2019-10-30 22:04:32 +01:00

82 lines
2.0 KiB
Rust

use serenity::model::channel::Message;
use std::fmt;
use serenity::model::id::ChannelId;
use serde::de::DeserializeOwned;
use serenity::prelude::*;
mod pacman;
extern crate reqwest;
pub struct Handler;
pub type CommandHandler = dyn Fn(Context, Message);
struct Command {
trigger: String,
handler: Box<CommandHandler>,
}
unsafe impl Sync for Command {}
const PREFIX: char = '!';
impl EventHandler for Handler {
fn message(&self, ctx: Context, msg: Message) {
if msg.content.starts_with(PREFIX) {
if let Some(command) = COMMANDS
.iter()
.filter(|&c| msg.content.starts_with(&c.trigger))
.next()
{
(*command.handler)(ctx, msg);
};
}
}
}
lazy_static! {
static ref COMMANDS: Vec<Command> = {
let mut command_list = Vec::new();
command_list.push(Command::new("pacman", pacman::query_pacman));
command_list
};
}
impl Command {
pub fn new(trigger: &str, handler: fn(Context, Message)) -> Self {
let mut trigger_with_prefix = trigger.to_string();
trigger_with_prefix.insert(0, PREFIX);
Self {
trigger: trigger_with_prefix,
handler: Box::new(handler),
}
}
}
pub fn send(target: ChannelId, message: &str, ctx: &Context) {
if let Err(cause) = target.say(&ctx.http, message) {
println!("Could not send message: {}", cause);
}
}
pub fn respond_with_results<T: fmt::Display>(target: ChannelId, results: &Vec<T>, ctx: &Context) {
send(
target,
&format!(
"```{}```",
results
.into_iter()
.take(5)
.map(|p| format!("{}\n", p))
.collect::<String>()
),
ctx,
);
}
pub fn search<T: DeserializeOwned>(url: &str, fallback: T) -> T {
return search_inner(url).unwrap_or(fallback);
}
fn search_inner<T: DeserializeOwned>(url: &str) -> Result<T, reqwest::Error> {
let resp = reqwest::get(url)?.json::<T>()?;
Ok(resp)
}