mod horse; mod joke; mod react; mod starboard; mod sus; mod xbasic; use crate::handlers::horse::HorseHandler; use crate::handlers::joke::*; use crate::handlers::react::*; use crate::handlers::starboard::StarboardHandler; use crate::handlers::sus::*; use crate::handlers::xbasic::*; use diesel::{Connection, PgConnection}; use dotenv::dotenv; use serenity::async_trait; use serenity::model::channel::Message; use serenity::model::prelude::{Reaction, Ready}; use serenity::prelude::*; use std::env; use std::sync::Arc; use tokio::sync::Mutex; #[async_trait] pub(crate) trait LineHandler: Send + Sync { async fn message(&self, ctx: &Context, msg: &Message) { for line in msg.content.split('\n') { self.line(ctx, msg, line).await } } async fn line(&self, _ctx: &Context, _msg: &Message, _line: &str) {} } #[async_trait] pub(crate) trait ReactionHandler: Send + Sync { async fn reaction_add(&self, ctx: &Context, reaction: &Reaction); async fn reaction_del(&self, ctx: &Context, reaction: &Reaction); } pub(crate) struct Dispatcher { handlers: Vec<Box<dyn LineHandler>>, reacts: Vec<Box<dyn ReactionHandler>>, } #[async_trait] impl EventHandler for Dispatcher { async fn message(&self, ctx: Context, msg: Message) { for h in &self.handlers { h.message(&ctx, &msg).await; } } async fn reaction_add(&self, ctx: Context, reaction: Reaction) { for r in &self.reacts { r.reaction_add(&ctx, &reaction).await; } } async fn reaction_remove(&self, ctx: Context, reaction: Reaction) { for r in &self.reacts { r.reaction_del(&ctx, &reaction).await; } } async fn ready(&self, _: Context, ready: Ready) { println!("{} is connected", ready.user.name); } } impl Default for Dispatcher { fn default() -> Self { let conn = Arc::new(Mutex::new(establish_connection())); Self { handlers: vec![ Box::new(XbasicHandler::new(conn.clone())), Box::new(JokeHandler::default()), Box::new(ReactHandler::default()), Box::new(SusHandler::default()), Box::new(HorseHandler::default()), ], reacts: vec![Box::new(StarboardHandler::new(conn))], } } } fn establish_connection() -> PgConnection { dotenv().ok(); let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); PgConnection::establish(&database_url).expect("Error connecting to database") }