NON EXHAUSTIVE SHOULD BE A FUCKING WARNING

This commit is contained in:
jellywx 2022-02-01 15:30:35 +00:00
parent e436d9db80
commit 32be8a4281
3 changed files with 105 additions and 10 deletions

View File

@ -6,8 +6,11 @@ use poise::CreateReply;
use crate::{
consts::{EMBED_DESCRIPTION_MAX_LENGTH, THEME_COLOR},
hooks::guild_only,
models::{command_macro::CommandMacro, CtxData},
Context, Error,
models::{
command_macro::{CommandMacro, CommandOptions},
CtxData,
},
Context, Data, Error,
};
async fn timezone_autocomplete(ctx: Context<'_>, partial: String) -> Vec<String> {
@ -303,6 +306,26 @@ pub async fn list_macro(ctx: Context<'_>) -> Result<(), Error> {
Ok(())
}
fn find_command<'a>(
commands: &'a [poise::Command<Data, Error>],
searching_name: &str,
command_options: &CommandOptions,
) -> Option<&'a poise::Command<Data, Error>> {
commands.iter().find_map(|cmd| {
if searching_name != cmd.name {
None
} else {
if let Some(subgroup) = &command_options.subcommand_group {
find_command(&cmd.subcommands, &subgroup, &command_options)
} else if let Some(subcommand) = &command_options.subcommand {
find_command(&cmd.subcommands, &subcommand, &command_options)
} else {
Some(cmd)
}
}
})
}
/// Run a recorded macro
#[poise::command(slash_command, rename = "run", check = "guild_only")]
pub async fn run_macro(
@ -323,7 +346,24 @@ SELECT commands FROM macro WHERE guild_id = (SELECT id FROM guilds WHERE guild =
Ok(row) => {
ctx.defer().await?;
// TODO TODO TODO!!!!!!!! RUN COMMAND FROM MACRO
let commands: Vec<CommandOptions> = serde_json::from_str(&row.commands)?;
for command in commands {
let cmd =
find_command(&ctx.framework().options().commands, &command.command, &command);
if let Some(cmd) = cmd {
let mut executing_ctx = ctx.clone();
executing_ctx.command = cmd;
} else {
ctx.send(|m| {
m.ephemeral(true)
.content(format!("Command `{}` not found", command.command))
})
.await?;
}
}
}
Err(sqlx::Error::RowNotFound) => {

View File

@ -24,7 +24,7 @@ async fn macro_check(ctx: Context<'_>) -> bool {
if let Some(command_macro) = lock.get_mut(&(guild_id, ctx.author().id)) {
if command_macro.commands.len() >= MACRO_MAX_COMMANDS {
let _ = ctx.send(|m| {
m.ephemeral(false).content(
m.ephemeral(true).content(
"5 commands already recorded. Please use `/macro finish` to end recording.",
)
})
@ -36,7 +36,7 @@ async fn macro_check(ctx: Context<'_>) -> bool {
command_macro.commands.push(command_options);
let _ = ctx
.send(|m| m.ephemeral(false).content("Command recorded to macro"))
.send(|m| m.ephemeral(true).content("Command recorded to macro"))
.await;
}

View File

@ -1,13 +1,21 @@
use std::collections::HashMap;
use poise::serenity::model::{
id::{ChannelId, GuildId, RoleId, UserId},
interactions::application_command::{
ApplicationCommandInteraction, ApplicationCommandInteractionDataOption,
ApplicationCommandOptionType,
use poise::{
serenity::{
json::Value,
model::{
id::{ChannelId, GuildId, RoleId, UserId},
interactions::application_command::{
ApplicationCommandInteraction, ApplicationCommandInteractionData,
ApplicationCommandInteractionDataOption, ApplicationCommandOptionType,
ApplicationCommandType,
},
},
},
ApplicationCommandOrAutocompleteInteraction,
};
use serde::{Deserialize, Serialize};
use serde_json::Number;
use sqlx::Executor;
use crate::Database;
@ -90,6 +98,32 @@ impl OptionValue {
OptionValue::Number(n) => n.to_string(),
}
}
fn as_value(&self) -> Value {
match self {
OptionValue::String(s) => Value::String(s.to_string()),
OptionValue::Integer(i) => Value::Number(i.to_owned().into()),
OptionValue::Boolean(b) => Value::Bool(b.to_owned()),
OptionValue::User(u) => Value::String(u.to_string()),
OptionValue::Channel(c) => Value::String(c.to_string()),
OptionValue::Role(r) => Value::String(r.to_string()),
OptionValue::Mentionable(m) => Value::String(m.to_string()),
OptionValue::Number(n) => Value::Number(Number::from_f64(n.to_owned()).unwrap()),
}
}
fn kind(&self) -> ApplicationCommandOptionType {
match self {
OptionValue::String(_) => ApplicationCommandOptionType::String,
OptionValue::Integer(_) => ApplicationCommandOptionType::Integer,
OptionValue::Boolean(_) => ApplicationCommandOptionType::Boolean,
OptionValue::User(_) => ApplicationCommandOptionType::User,
OptionValue::Channel(_) => ApplicationCommandOptionType::Channel,
OptionValue::Role(_) => ApplicationCommandOptionType::Role,
OptionValue::Mentionable(_) => ApplicationCommandOptionType::Mentionable,
OptionValue::Number(_) => ApplicationCommandOptionType::Number,
}
}
}
#[derive(Serialize, Deserialize, Clone)]
@ -100,6 +134,27 @@ pub struct CommandOptions {
pub options: HashMap<String, OptionValue>,
}
impl Into<ApplicationCommandInteractionData> for CommandOptions {
fn into(self) -> ApplicationCommandInteractionData {
ApplicationCommandInteractionData {
name: self.command,
kind: ApplicationCommandType::ChatInput,
options: self
.options
.iter()
.map(|(name, value)| ApplicationCommandInteractionDataOption {
name: name.to_string(),
value: Some(value.as_value()),
kind: value.kind(),
options: vec![],
..Default::default()
})
.collect(),
..Default::default()
}
}
}
impl CommandOptions {
pub fn new(command: impl ToString) -> Self {
Self {