94 lines
2.8 KiB
Rust
94 lines
2.8 KiB
Rust
use ahhhh::YellResponder;
|
|
use all_caps::AllCapsResponder;
|
|
use best_doctor::BestDoctorResponder;
|
|
use desu::DesuResponder;
|
|
use futures::future::BoxFuture;
|
|
use rand::{rngs::OsRng, seq::IteratorRandom};
|
|
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<Box<dyn PassiveResponder + Send + Sync>>,
|
|
}
|
|
|
|
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) {
|
|
let received_msg = message.content_safe(ctx.clone()).await;
|
|
let valid_responses = self.responders.iter().filter_map(|responder| {
|
|
responder.get_message(received_msg.clone(), ctx.clone(), message.clone())
|
|
});
|
|
|
|
if let Some(fut) = valid_responses.choose(&mut OsRng) {
|
|
if let Err(err) = fut.await {
|
|
log::warn!("Got an error while sending a passive response: {}", err);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[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;
|
|
|
|
impl crate::passive::PassiveResponder for $name {
|
|
fn get_message(
|
|
&self,
|
|
received_msg: String,
|
|
ctx: serenity::prelude::Context,
|
|
message: serenity::model::channel::Message,
|
|
) -> Option<crate::passive::PassiveResponse<'_>> {
|
|
if REGEX.is_match(&received_msg) {
|
|
log::trace!("{} matched regex {:?}", received_msg, REGEX);
|
|
Some(Box::pin(crate::util::debug_say_owned(
|
|
message, ctx, $phrase,
|
|
)))
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
type PassiveResponse<'a> = BoxFuture<'a, Result<Option<Message>, serenity::Error>>;
|
|
|
|
trait PassiveResponder {
|
|
fn get_message(
|
|
&self,
|
|
received_msg: String,
|
|
ctx: Context,
|
|
message: Message,
|
|
) -> Option<PassiveResponse>;
|
|
}
|