use ahhhh::YellResponder; use all_caps::AllCapsResponder; use best_doctor::BestDoctorResponder; use desu::DesuResponder; use reee::ReeeResponder; use serenity::async_trait; use serenity::model::channel::Message; use serenity::prelude::{Context, EventHandler}; mod ahhhh; mod all_caps; mod best_doctor; mod desu; mod reee; pub(crate) struct Handler { responders: Vec>, } impl Default for Handler { fn default() -> Self { Self { responders: vec![ Box::new(BestDoctorResponder), Box::new(DesuResponder), Box::new(YellResponder), Box::new(ReeeResponder), Box::new(AllCapsResponder), ], } } } #[async_trait] impl EventHandler for Handler { async fn message(&self, ctx: Context, message: Message) { for responder in self.responders.iter() { responder.message(ctx.clone(), message.clone()).await; } } } #[macro_export] macro_rules! simple_responder { // $phrase should be `expr`, see https://github.com/dtolnay/async-trait/issues/46 // above issue is blocked on rustc bug, see https://github.com/rust-lang/rust/issues/43081 ($name:tt, $regex:expr, $phrase:tt) => { lazy_static::lazy_static! { #[derive(Debug)] static ref REGEX: regex::Regex = regex::Regex::new($regex).unwrap(); } pub(crate) struct $name; #[serenity::async_trait] impl serenity::prelude::EventHandler for $name { async fn message( &self, ctx: serenity::prelude::Context, message: serenity::model::channel::Message, ) { let msg = message.content_safe(ctx.clone()).await; if REGEX.is_match(&msg) { log::trace!("{} matched regex {:?}", msg, REGEX); message.channel_id.say(ctx, $phrase).await.unwrap(); } } } }; }