Skip to content
Snippets Groups Projects
mod.rs 2.28 KiB
Newer Older
Stephen D's avatar
Stephen D committed
mod horse;
Stephen D's avatar
Stephen D committed
mod joke;
mod react;
Stephen D's avatar
Stephen D committed
mod starboard;
Stephen D's avatar
Stephen D committed
mod sus;
Stephen D's avatar
Stephen D committed
mod xbasic;

Stephen D's avatar
Stephen D committed
use crate::handlers::horse::HorseHandler;
Stephen D's avatar
Stephen D committed
use crate::handlers::joke::*;
use crate::handlers::react::*;
Stephen D's avatar
Stephen D committed
use crate::handlers::starboard::StarboardHandler;
Stephen D's avatar
Stephen D committed
use crate::handlers::sus::*;
Stephen D's avatar
Stephen D committed
use crate::handlers::xbasic::*;

use diesel::{Connection, PgConnection};
use dotenv::dotenv;
Stephen D's avatar
Stephen D committed
use serenity::async_trait;
use serenity::model::channel::Message;
Stephen D's avatar
Stephen D committed
use serenity::model::prelude::{Reaction, Ready};
Stephen D's avatar
Stephen D committed
use serenity::prelude::*;
use std::env;
Stephen D's avatar
Stephen D committed
use std::sync::Arc;
use tokio::sync::Mutex;
Stephen D's avatar
Stephen D committed

#[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) {}
}

Stephen D's avatar
Stephen D committed
#[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);
Stephen D's avatar
Stephen D committed
}

Stephen D's avatar
Stephen D committed
pub(crate) struct Dispatcher {
	handlers: Vec<Box<dyn LineHandler>>,
Stephen D's avatar
Stephen D committed
	reacts: Vec<Box<dyn ReactionHandler>>,
Stephen D's avatar
Stephen D committed
}

#[async_trait]
impl EventHandler for Dispatcher {
	async fn message(&self, ctx: Context, msg: Message) {
		for h in &self.handlers {
			h.message(&ctx, &msg).await;
		}
	}

Stephen D's avatar
Stephen D committed
	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;
Stephen D's avatar
Stephen D committed
		}
	}

Stephen D's avatar
Stephen D committed
	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()));

Stephen D's avatar
Stephen D committed
		Self {
			handlers: vec![
Stephen D's avatar
Stephen D committed
				Box::new(XbasicHandler::new(conn.clone())),
Stephen D's avatar
Stephen D committed
				Box::new(JokeHandler::default()),
				Box::new(ReactHandler::default()),
Stephen D's avatar
Stephen D committed
				Box::new(SusHandler::default()),
Stephen D's avatar
Stephen D committed
				Box::new(HorseHandler::default()),
Stephen D's avatar
Stephen D committed
			],
Stephen D's avatar
Stephen D committed
			reacts: vec![Box::new(StarboardHandler::new(conn))],
Stephen D's avatar
Stephen D committed
		}
	}
}

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")
}