From 8a05968b31cb4c0ffe56fedbab1c881a37fecdd4 Mon Sep 17 00:00:00 2001 From: Jacher Date: Wed, 12 Jun 2024 20:51:03 +0000 Subject: [PATCH] properly support interaction subcommands w/ default subcommand --- assyst-core/src/command/arguments.rs | 36 +++++++++++++++++++++------- assyst-core/src/command/errors.rs | 11 ++++++++- assyst-core/src/command/group.rs | 15 ++++++++---- assyst-core/src/command/misc/tag.rs | 3 ++- 4 files changed, 50 insertions(+), 15 deletions(-) diff --git a/assyst-core/src/command/arguments.rs b/assyst-core/src/command/arguments.rs index da62a64..16e9617 100644 --- a/assyst-core/src/command/arguments.rs +++ b/assyst-core/src/command/arguments.rs @@ -502,12 +502,21 @@ impl ParseArgument for ImageUrl { }; } - handle!(ctxt.commit_if_ok(ImageUrl::from_mention_raw_message).await); - handle!(ctxt.commit_if_ok(ImageUrl::from_url_argument_raw_message).await); - handle!(ctxt.commit_if_ok(ImageUrl::from_attachment).await); - handle!(ctxt.commit_if_ok(ImageUrl::from_reply).await); - handle!(ctxt.commit_if_ok(ImageUrl::from_emoji_raw_message).await); - handle!(ctxt.commit_if_ok(ImageUrl::from_sticker).await); + handle!( + ctxt.commit_if_ok(async |v| ImageUrl::from_mention_raw_message(v).await) + .await + ); + handle!( + ctxt.commit_if_ok(async |v| ImageUrl::from_url_argument_raw_message(v).await) + .await + ); + handle!(ctxt.commit_if_ok(async |v| ImageUrl::from_attachment(v).await).await); + handle!(ctxt.commit_if_ok(async |v| ImageUrl::from_reply(v).await).await); + handle!( + ctxt.commit_if_ok(async |v| ImageUrl::from_emoji_raw_message(v).await) + .await + ); + handle!(ctxt.commit_if_ok(async |v| ImageUrl::from_sticker(v).await).await); handle!(ImageUrl::from_channel_history(ctxt.cx.assyst(), ctxt.cx.data.message.channel_id).await); Err(TagParseError::NoImageFound) } @@ -538,9 +547,18 @@ impl ParseArgument for ImageUrl { }; } - handle!(ctxt.commit_if_ok(ImageUrl::from_mention_command_option).await); - handle!(ctxt.commit_if_ok(ImageUrl::from_url_argument_command_option).await); - handle!(ctxt.commit_if_ok(ImageUrl::from_emoji_command_option).await); + handle!( + ctxt.commit_if_ok(async |v| ImageUrl::from_mention_command_option(v).await) + .await + ); + handle!( + ctxt.commit_if_ok(async |v| ImageUrl::from_url_argument_command_option(v).await) + .await + ); + handle!( + ctxt.commit_if_ok(async |v| ImageUrl::from_emoji_command_option(v).await) + .await + ); handle!(ImageUrl::from_channel_history(ctxt.cx.assyst(), ctxt.cx.data.message.channel_id).await); Err(TagParseError::NoImageFound) } diff --git a/assyst-core/src/command/errors.rs b/assyst-core/src/command/errors.rs index 2c017ec..ddd79b5 100644 --- a/assyst-core/src/command/errors.rs +++ b/assyst-core/src/command/errors.rs @@ -95,6 +95,8 @@ pub enum TagParseError { NoImageFound, MediaDownloadFail, InvalidSubcommand, + NoInteractionSubcommandProvided, + InteractionCommandIsBaseSubcommand, MismatchedCommandOptionType((String, CommandOptionValue)), } @@ -105,7 +107,8 @@ impl GetErrorSeverity for TagParseError { | Self::TwilightDeserialize(..) | Self::DownloadError(..) | Self::UnsupportedSticker(..) - | Self::Reqwest(..) => ErrorSeverity::High, + | Self::Reqwest(..) + | Self::NoInteractionSubcommandProvided => ErrorSeverity::High, _ => ErrorSeverity::Low, } } @@ -150,6 +153,12 @@ impl Display for TagParseError { "Command option mismatch between expected ({expected}) and received ({received:?})" ) }, + TagParseError::NoInteractionSubcommandProvided => { + f.write_str("Attempted to execute an interaction base command on a command group") + }, + TagParseError::InteractionCommandIsBaseSubcommand => { + f.write_str("Interaction subcommand is base subcommand") + }, } } } diff --git a/assyst-core/src/command/group.rs b/assyst-core/src/command/group.rs index bb628cd..513ebbe 100644 --- a/assyst-core/src/command/group.rs +++ b/assyst-core/src/command/group.rs @@ -43,6 +43,7 @@ macro_rules! define_commandgroup { $subcommand:literal => $commandfn:expr ),* ] + default_interaction_subcommand: $default_interaction_subcommand:expr $(,default: $default:expr)? ) => { paste::paste! { @@ -82,6 +83,7 @@ macro_rules! define_commandgroup { } fn interaction_info(&self) -> crate::command::CommandInteractionInfo { + // todo todo!() } @@ -128,10 +130,10 @@ macro_rules! define_commandgroup { async fn execute_interaction_command(&self, ctxt: crate::command::InteractionCommandParseCtxt<'_>) -> Result<(), crate::command::ExecutionError> { #![allow(unreachable_code)] - match crate::command::group::execute_subcommand_interaction_command(ctxt.fork(), Self::SUBCOMMANDS).await { + match crate::command::group::execute_subcommand_interaction_command(ctxt.fork(), Self::SUBCOMMANDS, $default_interaction_subcommand).await { Ok(res) => Ok(res), - Err(crate::command::ExecutionError::Parse(crate::command::errors::TagParseError::InvalidSubcommand)) => { - // No subcommand was found, call either the default if provided, or error out + Err(crate::command::ExecutionError::Parse(crate::command::errors::TagParseError::InteractionCommandIsBaseSubcommand)) => { + // Subcommand was "defau;t" command, call either the default if provided, or error out $( return [<$default _command>].execute_interaction_command(ctxt).await; )? @@ -171,14 +173,19 @@ pub fn find_subcommand_interaction_command(sub: &str, cmds: &[(&str, TCommand)]) pub async fn execute_subcommand_interaction_command( ctxt: InteractionCommandParseCtxt<'_>, commands: &[(&str, TCommand)], + default_interaction_subcommand: &str ) -> Result<(), ExecutionError> { - let subcommand = ctxt.cx.data.interaction_subcommand.clone().ok_or(ExecutionError::Parse(TagParseError::ArgsExhausted))?; + let subcommand = ctxt.cx.data.interaction_subcommand.clone().ok_or(ExecutionError::Parse(TagParseError::NoInteractionSubcommandProvided))?; let subcommand = if let CommandOptionValue::SubCommand(c) = subcommand { c.get(0).map(|x| x.name.clone()).unwrap() } else { unreachable!() }; + if subcommand == default_interaction_subcommand { + return Err(ExecutionError::Parse(TagParseError::InteractionCommandIsBaseSubcommand)); + } + let command = find_subcommand_interaction_command(&subcommand, commands).ok_or(ExecutionError::Parse(TagParseError::InvalidSubcommand))?; diff --git a/assyst-core/src/command/misc/tag.rs b/assyst-core/src/command/misc/tag.rs index c81e195..ec2eebc 100644 --- a/assyst-core/src/command/misc/tag.rs +++ b/assyst-core/src/command/misc/tag.rs @@ -185,6 +185,7 @@ define_commandgroup! { usage: "", commands: [ "create" => create - ], + ] + default_interaction_subcommand: "view", default: default }