use diesel::{ result::Error as DieselError, NotFound, }; use log::info; use crate::{ commands::meme::send_meme, db::{ self, connection, find_meme, InvocationRecord, }, util, PoiseContext, }; #[poise::command(slash_command, prefix_command, guild_only, category = "memes", aliases("mem"))] pub async fn meme(ctx: PoiseContext<'_>, #[rest] rest: String) -> anyhow::Result<()> { _meme(ctx, rest, AudioPlayback::Optional).await } #[poise::command(slash_command, prefix_command, guild_only, category = "memes")] pub async fn omen(ctx: PoiseContext<'_>) -> anyhow::Result<()> { _meme(ctx, "", AudioPlayback::Optional).await } #[poise::command(slash_command, prefix_command, guild_only, category = "memes")] pub async fn silentomen(ctx: PoiseContext<'_>) -> anyhow::Result<()> { _meme(ctx, "", AudioPlayback::Prohibited).await } #[poise::command(slash_command, prefix_command, guild_only, category = "memes")] pub async fn audioomen(ctx: PoiseContext<'_>) -> anyhow::Result<()> { _meme(ctx, "", AudioPlayback::Required).await } #[poise::command( slash_command, prefix_command, guild_only, category = "memes", aliases("audiomeme", "audiomem") )] pub async fn audio_meme(ctx: PoiseContext<'_>, #[rest] rest: String) -> anyhow::Result<()> { _meme(ctx, rest, AudioPlayback::Required).await } #[poise::command( slash_command, prefix_command, guild_only, category = "memes", aliases("silentmeme", "silentmem") )] pub async fn silent_meme(ctx: PoiseContext<'_>, #[rest] rest: String) -> anyhow::Result<()> { _meme(ctx, rest, AudioPlayback::Prohibited).await } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] enum AudioPlayback { Required, Optional, Prohibited, } async fn _meme( ctx: PoiseContext<'_>, args: impl AsRef, audio_playback: AudioPlayback, ) -> anyhow::Result<()> { let args = args.as_ref().trim(); if args.is_empty() || audio_playback != AudioPlayback::Optional { return rand_meme(ctx, audio_playback).await; } let mut conn = connection().await?; let mem = match find_meme(&mut conn, args).await { Ok(x) => { InvocationRecord::create(&mut conn, ctx.author().id.get(), ctx.id(), x.id, false) .await?; x }, Err(e) => { return if let Some(NotFound) = e.downcast_ref::() { info!("requested meme not found in database"); util::reply(ctx, "c'mon baby, guesstimate").await?; Ok(()) } else { util::reply(ctx, "what in ryan's name").await?; Err(e.into()) }; }, }; send_meme(ctx, &mem, &mut conn).await } async fn rand_meme(ctx: PoiseContext<'_>, audio_playback: AudioPlayback) -> anyhow::Result<()> { let mut conn = connection().await?; let should_audio = util::users_listening(ctx.serenity_context()).await?; let mem = match audio_playback { AudioPlayback::Required => db::rand_audio_meme(&mut conn).await, AudioPlayback::Optional => db::rand_meme(&mut conn, should_audio).await, AudioPlayback::Prohibited => db::rand_silent_meme(&mut conn).await, }; match mem { Ok(mem) => { InvocationRecord::create(&mut conn, ctx.author().id.get(), ctx.id(), mem.id, true) .await?; send_meme(ctx, &mem, &mut conn).await?; Ok(()) }, Err(e) => { if let Some(NotFound) = e.downcast_ref::() { info!("random meme not found"); util::reply(ctx, "i don't know any :(").await?; return Ok(()); } util::reply(ctx, "HELP").await?; Err(e.into()) }, } } #[poise::command( slash_command, prefix_command, guild_only, category = "memes", aliases("raremem", "rarememe") )] pub async fn rare_meme(ctx: PoiseContext<'_>) -> anyhow::Result<()> { let should_audio = util::users_listening(ctx.serenity_context()).await?; let mut conn = connection().await?; let meme = db::rare_meme(&mut conn, should_audio).await; match meme { Ok(meme) => { InvocationRecord::create(&mut conn, ctx.author().id.get(), ctx.id(), meme.id, true) .await?; send_meme(ctx, &meme, &mut conn).await }, Err(e) => { if let Some(NotFound) = e.downcast_ref::() { info!("rare meme not found"); util::reply(ctx, "i don't know any :(").await?; return Ok(()); } util::reply(ctx, "THE MEME MARKET IS IN FREEFALL").await?; Err(e.into()) }, } }