use std::collections::hash_map::Entry; use poise::{serenity_prelude::CreateEmbed, CreateReply}; use crate::{consts::THEME_COLOR, models::command_macro::CommandMacro, Context, Error}; /// Start recording up to 5 commands to replay #[poise::command( slash_command, rename = "record", guild_only = true, default_member_permissions = "MANAGE_GUILD", identifying_name = "record_macro" )] pub async fn record_macro( ctx: Context<'_>, #[description = "Name for the new macro"] name: String, #[description = "Description for the new macro"] description: Option, ) -> Result<(), Error> { if name.len() > 100 { ctx.say("Name must be less than 100 characters").await?; return Ok(()); } if description.as_ref().map_or(0, |d| d.len()) > 100 { ctx.say("Description must be less than 100 characters").await?; return Ok(()); } let guild_id = ctx.guild_id().unwrap(); let row = sqlx::query!( " SELECT 1 as _e FROM command_macro WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?) AND name = ? ", guild_id.get(), name ) .fetch_one(&ctx.data().database) .await; if row.is_ok() { ctx.send( CreateReply::default().ephemeral(true).embed( CreateEmbed::new() .title("Unique Name Required") .description( "A macro already exists under this name. Please select a unique name for your macro.", ) .color(*THEME_COLOR), ), ) .await?; } else { let okay = { let mut lock = ctx.data().recording_macros.write().await; if let Entry::Vacant(e) = lock.entry((guild_id, ctx.author().id)) { e.insert(CommandMacro { guild_id, name, description, commands: vec![] }); true } else { false } }; if okay { ctx.send( CreateReply::default().ephemeral(true).embed( CreateEmbed::new() .title("Macro Recording Started") .description( "Run up to 5 commands, or type `/macro finish` to stop at any point. Any commands ran as part of recording will be inconsequential", ) .color(*THEME_COLOR), ), ) .await?; } else { ctx.send( CreateReply::default().ephemeral(true).embed( CreateEmbed::new() .title("Macro Already Recording") .description( "You are already recording a macro in this server. Please use `/macro finish` to end this recording before starting another.", ) .color(*THEME_COLOR), ), ) .await?; } } Ok(()) }