From a57fa13004af70fc5c47f92d8b07f6eedaafd905 Mon Sep 17 00:00:00 2001 From: Edward Shen Date: Fri, 1 May 2020 22:17:53 -0400 Subject: [PATCH] refactor --- src/commands/clap.rs | 23 +++++ src/commands/cube.rs | 72 ++++++++++++++ src/commands/heck.rs | 17 ++++ src/commands/mod.rs | 10 ++ src/main.rs | 186 ++----------------------------------- src/passive/best_doctor.rs | 30 ++++++ src/passive/fufufu.rs | 60 ++++++++++++ src/passive/mod.rs | 76 +++++++++++++++ src/passive/yell_resp.rs | 30 ++++++ 9 files changed, 326 insertions(+), 178 deletions(-) create mode 100644 src/commands/clap.rs create mode 100644 src/commands/cube.rs create mode 100644 src/commands/heck.rs create mode 100644 src/commands/mod.rs create mode 100644 src/passive/best_doctor.rs create mode 100644 src/passive/fufufu.rs create mode 100644 src/passive/mod.rs create mode 100644 src/passive/yell_resp.rs diff --git a/src/commands/clap.rs b/src/commands/clap.rs new file mode 100644 index 0000000..5bd44fe --- /dev/null +++ b/src/commands/clap.rs @@ -0,0 +1,23 @@ +use serenity::framework::standard::{macros::command, Args, CommandResult}; +use serenity::model::channel::Message; +use serenity::prelude::Context; + +#[command] +async fn clap(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult { + let resp = match args + .iter() + .map(|e: Result| e.unwrap()) + .collect::>() + .as_slice() + { + [] => ":clap:".to_string(), + [_] => "You can't clap a single word." + .split_whitespace() + .collect::>() + .join(" :clap: "), + args => args.join(" :clap: "), + }; + + msg.channel_id.say(ctx, resp).await?; + Ok(()) +} diff --git a/src/commands/cube.rs b/src/commands/cube.rs new file mode 100644 index 0000000..f92b11f --- /dev/null +++ b/src/commands/cube.rs @@ -0,0 +1,72 @@ +use serenity::framework::standard::{macros::command, Args, CommandResult}; +use serenity::model::channel::Message; +use serenity::prelude::Context; +use unicode_segmentation::UnicodeSegmentation; + +#[command] +pub(crate) async fn cube(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult { + let resp = match args + .iter() + .map(|e: Result| e.unwrap()) + .collect::>() + .as_slice() + { + [] => "What do you wanna cube?".to_string(), + args => { + let to_cube: &str = &args.join(" "); + let to_cube = UnicodeSegmentation::graphemes(to_cube, true).collect::>(); + let cube_len = to_cube.len(); + let should_reverse = to_cube.last() != to_cube.first(); + + let offset = cube_len / 2; + let mut field = + vec![vec![" ".to_string(); (cube_len + offset) * 2 - 1]; cube_len + offset]; + + draw_diagonal(&mut field, cube_len, offset); + draw_box(&mut field, &to_cube, should_reverse, offset * 2, 0); + draw_box(&mut field, &to_cube, should_reverse, 0, offset); + + let text = field + .iter() + .map(|r| r.join("").trim_end().to_string()) + .collect::>() + .join("\n"); + + ["```\n".to_string(), text, "```".to_string()].concat() + } + }; + + msg.channel_id.say(ctx, resp).await?; + + Ok(()) +} + +fn draw_diagonal(field: &mut Vec>, cube_len: usize, offset: usize) { + let diag_char = "/".to_string(); + for x in 0..offset { + field[offset - x][x * 2] = diag_char.clone(); + field[cube_len - x + offset - 1][x * 2] = diag_char.clone(); + field[offset - x][(x + cube_len - 1) * 2] = diag_char.clone(); + field[cube_len - x + offset - 1][(x + cube_len - 1) * 2] = diag_char.clone(); + } +} + +fn draw_box(field: &mut Vec>, chars: &[&str], should_rev: bool, x: usize, y: usize) { + let word_len = chars.len(); + + // Magic numbers are good as long as they're 1 or 2 right? + for i in 0..word_len { + field[y + i][x] = chars[i].to_string(); + field[y][x + i * 2] = chars[i].to_string(); + field[y + (word_len - 1)][x + (word_len - 1 - i) * 2] = if should_rev { + chars[i].to_string() + } else { + chars[word_len - i - 1].to_string() + }; + field[y + (word_len - 1) - i][x + (word_len - 1) * 2] = if should_rev { + chars[i].to_string() + } else { + chars[word_len - i - 1].to_string() + }; + } +} diff --git a/src/commands/heck.rs b/src/commands/heck.rs new file mode 100644 index 0000000..e95fc3e --- /dev/null +++ b/src/commands/heck.rs @@ -0,0 +1,17 @@ +use crate::DbConnPool; +use serenity::framework::standard::{macros::command, CommandResult}; +use serenity::model::channel::Message; +use serenity::prelude::Context; + +#[command] +async fn heck(ctx: &mut Context, msg: &Message) -> CommandResult { + let db_pool = ctx.data.clone(); + let mut db_pool = db_pool.write().await; + let db_pool = db_pool.get_mut::().unwrap(); + let value = db_pool.get_heck().await; + msg.channel_id + .say(ctx, format!("This command has been hecked {} times", value)) + .await?; + + Ok(()) +} diff --git a/src/commands/mod.rs b/src/commands/mod.rs new file mode 100644 index 0000000..3bd89e7 --- /dev/null +++ b/src/commands/mod.rs @@ -0,0 +1,10 @@ +use crate::commands::{clap::CLAP_COMMAND, cube::CUBE_COMMAND, heck::HECK_COMMAND}; +use serenity::framework::standard::macros::group; + +mod clap; +mod cube; +mod heck; + +#[group] +#[commands(heck, clap, cube)] +pub(crate) struct General; diff --git a/src/main.rs b/src/main.rs index 9c78b02..59fbf09 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,87 +1,17 @@ -use regex::Regex; -use serenity::async_trait; +use crate::commands::GENERAL_GROUP; +use crate::passive::Handler; use serenity::client::Client; -use serenity::framework::standard::{ - macros::{command, group}, - CommandResult, StandardFramework, -}; -use serenity::model::channel::Message; -use serenity::prelude::{Context, EventHandler, TypeMapKey}; +use serenity::framework::standard::StandardFramework; +use serenity::prelude::TypeMapKey; use sqlx::sqlite::SqlitePool; use std::env; -use unicode_segmentation::UnicodeSegmentation; -const COMMAND_PREFIX: &str = "~"; +mod commands; +mod passive; -struct Handler { - ah_regex: Regex, - best_doctor_regex: Regex, - fufufu_regex: Regex, -} +pub(crate) const COMMAND_PREFIX: &str = "~"; -impl Default for Handler { - fn default() -> Self { - Self { - ah_regex: Regex::new(r"A+H{5,}").unwrap(), - best_doctor_regex: Regex::new(r"[iI].*(?:best|genius) doc").unwrap(), - fufufu_regex: Regex::new(r"(?:[fF][uU]){3,}").unwrap(), - } - } -} - -#[async_trait] -impl EventHandler for Handler { - async fn message(&self, ctx: Context, message: Message) { - let content = &message.content_safe(ctx.clone()).await; - if self.ah_regex.is_match(content) { - message - .channel_id - .say(ctx, "its ok ur gonna get a 6* someday") - .await - .unwrap(); - } else if self.best_doctor_regex.is_match(content) { - message - .channel_id - .say(ctx, "no, u is smol brain doctor...") - .await - .unwrap(); - } else if self.fufufu_regex.is_match(content) { - message.channel_id.say(ctx, get_desu()).await.unwrap(); - } - } -} - -const DESU_STRINGS: &[&str] = &[ - "です。", - "desu~", - "desu.", - r#" -``` -ででででででででででで      すす -     ででで     すすすすすすすすす -    でで  でで      すす -   でで   でで     すすす -  でで           す す -  でで           すすす -   でで           すす -    でで          すす -     でで        すす -```"#, -]; - -fn get_desu() -> &'static str { - use rand::seq::SliceRandom; - use rand::thread_rng; - - DESU_STRINGS.choose(&mut thread_rng()).unwrap() - // // https://imgur.com/a/yOb5n - // messageList.add(channel -> channel.sendMessage(new MessageBuilder() - // .setContent("https://www.youtube.com/watch?v=60mLvBWOMb4").build())); - // messageList.add(channel -> channel.sendFile(Desu.class.getResourceAsStream("/desu/desu.jpg"), "desu.jpg")); - // messageList.add(channel -> channel.sendMessage("desu~")); -} - -struct DbConnPool { +pub(crate) struct DbConnPool { pool: sqlx::pool::Pool, } @@ -161,103 +91,3 @@ async fn init_pool(pool: &sqlx::pool::Pool) { .unwrap(); } } - -#[group] -#[commands(heck, clap, cube)] -struct General; -#[command] -async fn heck(ctx: &mut Context, msg: &Message) -> CommandResult { - let db_pool = ctx.data.clone(); - let mut db_pool = db_pool.write().await; - let db_pool = db_pool.get_mut::().unwrap(); - let value = db_pool.get_heck().await; - msg.channel_id - .say(ctx, format!("This command has been hecked {} times", value)) - .await?; - - Ok(()) -} - -#[command] -async fn clap(ctx: &mut Context, msg: &Message) -> CommandResult { - let content = msg.content_safe(ctx.cache.clone()).await; - let tokens: Vec<_> = content.split_whitespace().collect(); - let resp = match tokens.len() { - 1 => ":clap:".to_string(), - 2 => "You can't clap a single word." - .split_whitespace() - .collect::>() - .join(" :clap: "), - _ => tokens[1..].join(" :clap: "), - }; - - msg.channel_id.say(ctx, resp).await?; - Ok(()) -} - -#[command] -async fn cube(ctx: &mut Context, msg: &Message) -> CommandResult { - let mut original_msg = msg.content_safe(ctx.cache.clone()).await; - let tokens = original_msg.split_ascii_whitespace().collect::>(); - - let resp = match tokens.len() { - 0 => unreachable!("wat"), - 1 => "What do you wanna cube?".to_string(), - _ => { - let to_cube: &str = &original_msg.split_off(COMMAND_PREFIX.len() + "cube".len() + 1); - let to_cube = UnicodeSegmentation::graphemes(to_cube, true).collect::>(); - let cube_len = to_cube.len(); - let should_reverse = to_cube.last() != to_cube.first(); - - let offset = cube_len / 2; - let mut field = - vec![vec![" ".to_string(); (cube_len + offset) * 2 - 1]; cube_len + offset]; - - draw_diagonal(&mut field, cube_len, offset); - draw_box(&mut field, &to_cube, should_reverse, offset * 2, 0); - draw_box(&mut field, &to_cube, should_reverse, 0, offset); - - let text = field - .iter() - .map(|r| r.join("").trim_end().to_string()) - .collect::>() - .join("\n"); - - ["```\n".to_string(), text, "```".to_string()].concat() - } - }; - - msg.channel_id.say(ctx, resp).await?; - - Ok(()) -} - -fn draw_diagonal(field: &mut Vec>, cube_len: usize, offset: usize) { - let diag_char = "/".to_string(); - for x in 0..offset { - field[offset - x][x * 2] = diag_char.clone(); - field[cube_len - x + offset - 1][x * 2] = diag_char.clone(); - field[offset - x][(x + cube_len - 1) * 2] = diag_char.clone(); - field[cube_len - x + offset - 1][(x + cube_len - 1) * 2] = diag_char.clone(); - } -} - -fn draw_box(field: &mut Vec>, chars: &[&str], should_rev: bool, x: usize, y: usize) { - let word_len = chars.len(); - - // Magic numbers are good as long as they're 1 or 2 right? - for i in 0..word_len { - field[y + i][x] = chars[i].to_string(); - field[y][x + i * 2] = chars[i].to_string(); - field[y + (word_len - 1)][x + (word_len - 1 - i) * 2] = if should_rev { - chars[i].to_string() - } else { - chars[word_len - i - 1].to_string() - }; - field[y + (word_len - 1) - i][x + (word_len - 1) * 2] = if should_rev { - chars[i].to_string() - } else { - chars[word_len - i - 1].to_string() - }; - } -} diff --git a/src/passive/best_doctor.rs b/src/passive/best_doctor.rs new file mode 100644 index 0000000..ead7a5e --- /dev/null +++ b/src/passive/best_doctor.rs @@ -0,0 +1,30 @@ +use regex::Regex; +use serenity::async_trait; +use serenity::model::channel::Message; +use serenity::prelude::{Context, EventHandler}; + +pub(crate) struct BestDoctorResponder { + regex: Regex, +} + +impl Default for BestDoctorResponder { + fn default() -> Self { + Self { + regex: Regex::new(r"[iI].*(?:best|genius) doc").unwrap(), + } + } +} + +#[async_trait] +impl EventHandler for BestDoctorResponder { + async fn message(&self, ctx: Context, message: Message) { + let content = &message.content_safe(ctx.clone()).await; + if self.regex.is_match(content) { + message + .channel_id + .say(ctx, "its ok ur gonna get a 6* someday") + .await + .unwrap(); + } + } +} diff --git a/src/passive/fufufu.rs b/src/passive/fufufu.rs new file mode 100644 index 0000000..f3bd2fa --- /dev/null +++ b/src/passive/fufufu.rs @@ -0,0 +1,60 @@ +use regex::Regex; +use serenity::async_trait; +use serenity::model::channel::Message; +use serenity::prelude::{Context, EventHandler}; + +pub(crate) struct BestDoctorResponder { + regex: Regex, +} + +impl Default for BestDoctorResponder { + fn default() -> Self { + Self { + regex: Regex::new(r"(?:[fF][uU]){3,}").unwrap(), + } + } +} + +#[async_trait] +impl EventHandler for BestDoctorResponder { + async fn message(&self, ctx: Context, message: Message) { + let content = &message.content_safe(ctx.clone()).await; + if self.regex.is_match(content) { + message + .channel_id + .say(ctx, get_desu()) + .await + .unwrap(); + } + } +} + +const DESU_STRINGS: &[&str] = &[ + "です。", + "desu~", + "desu.", + r#" +``` +ででででででででででで      すす +     ででで     すすすすすすすすす +    でで  でで      すす +   でで   でで     すすす +  でで           す す +  でで           すすす +   でで           すす +    でで          すす +     でで        すす +```"#, +]; + +fn get_desu() -> &'static str { + use rand::seq::SliceRandom; + use rand::thread_rng; + + DESU_STRINGS.choose(&mut thread_rng()).unwrap() + // // https://imgur.com/a/yOb5n + // messageList.add(channel -> channel.sendMessage(new MessageBuilder() + // .setContent("https://www.youtube.com/watch?v=60mLvBWOMb4").build())); + // messageList.add(channel -> channel.sendFile(Desu.class.getResourceAsStream("/desu/desu.jpg"), "desu.jpg")); + // messageList.add(channel -> channel.sendMessage("desu~")); +} diff --git a/src/passive/mod.rs b/src/passive/mod.rs new file mode 100644 index 0000000..9ee32d1 --- /dev/null +++ b/src/passive/mod.rs @@ -0,0 +1,76 @@ +use regex::Regex; +use serenity::async_trait; +use serenity::model::channel::Message; +use serenity::prelude::{Context, EventHandler}; + +mod best_doctor; +mod fufufu; +mod yell_resp; + +pub(crate) struct Handler { + ah_regex: Regex, + best_doctor_regex: Regex, + fufufu_regex: Regex, +} + +impl Default for Handler { + fn default() -> Self { + Self { + ah_regex: Regex::new(r"A+H{5,}").unwrap(), + best_doctor_regex: Regex::new(r"[iI].*(?:best|genius) doc").unwrap(), + fufufu_regex: Regex::new(r"(?:[fF][uU]){3,}").unwrap(), + } + } +} + +#[async_trait] +impl EventHandler for Handler { + async fn message(&self, ctx: Context, message: Message) { + let content = &message.content_safe(ctx.clone()).await; + if self.ah_regex.is_match(content) { + message + .channel_id + .say(ctx, "its ok ur gonna get a 6* someday") + .await + .unwrap(); + } else if self.best_doctor_regex.is_match(content) { + message + .channel_id + .say(ctx, "no, u is smol brain doctor...") + .await + .unwrap(); + } else if self.fufufu_regex.is_match(content) { + message.channel_id.say(ctx, get_desu()).await.unwrap(); + } + } +} + +const DESU_STRINGS: &[&str] = &[ + "です。", + "desu~", + "desu.", + r#" +``` +ででででででででででで      すす +     ででで     すすすすすすすすす +    でで  でで      すす +   でで   でで     すすす +  でで           す す +  でで           すすす +   でで           すす +    でで          すす +     でで        すす +```"#, +]; + +fn get_desu() -> &'static str { + use rand::seq::SliceRandom; + use rand::thread_rng; + + DESU_STRINGS.choose(&mut thread_rng()).unwrap() + // // https://imgur.com/a/yOb5n + // messageList.add(channel -> channel.sendMessage(new MessageBuilder() + // .setContent("https://www.youtube.com/watch?v=60mLvBWOMb4").build())); + // messageList.add(channel -> channel.sendFile(Desu.class.getResourceAsStream("/desu/desu.jpg"), "desu.jpg")); + // messageList.add(channel -> channel.sendMessage("desu~")); +} diff --git a/src/passive/yell_resp.rs b/src/passive/yell_resp.rs new file mode 100644 index 0000000..70591d8 --- /dev/null +++ b/src/passive/yell_resp.rs @@ -0,0 +1,30 @@ +use regex::Regex; +use serenity::async_trait; +use serenity::model::channel::Message; +use serenity::prelude::{Context, EventHandler}; + +pub(crate) struct YellResponder { + regex: Regex, +} + +impl Default for YellResponder { + fn default() -> Self { + Self { + regex: Regex::new(r"A+H{5,}").unwrap(), + } + } +} + +#[async_trait] +impl EventHandler for YellResponder { + async fn message(&self, ctx: Context, message: Message) { + let content = &message.content_safe(ctx.clone()).await; + if self.regex.is_match(content) { + message + .channel_id + .say(ctx, "no, u is smol brain doctor..") + .await + .unwrap(); + } + } +}