Skip to content

Commit

Permalink
Add unstable feature flag
Browse files Browse the repository at this point in the history
  • Loading branch information
fgardt committed Jun 3, 2024
1 parent f4a2e40 commit 524d962
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 19 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ collector = []
# This feature exists because some users want to disable the mere possibility of catching panics at
# build time for peace of mind.
handle_panics = []
unstable = ["serenity/unstable_discord_api", "poise_macros/unstable"]

[package.metadata.docs.rs]
all-features = true
Expand Down
3 changes: 3 additions & 0 deletions macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ syn = { version = "2", features = ["fold"] }
quote = "1.0.9"
proc-macro2 = "1.0.24"
darling = "0.20"

[features]
unstable = []
70 changes: 69 additions & 1 deletion macros/src/command/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ pub struct CommandArgs {
category: Option<String>,
custom_data: Option<syn::Expr>,

#[cfg(feature = "unstable")]
install_context: Option<syn::punctuated::Punctuated<syn::Ident, syn::Token![|]>>,
#[cfg(feature = "unstable")]
interaction_context: Option<syn::punctuated::Punctuated<syn::Ident, syn::Token![|]>>,

// In seconds
Expand Down Expand Up @@ -100,7 +102,9 @@ pub struct Invocation {
default_member_permissions: syn::Expr,
required_permissions: syn::Expr,
required_bot_permissions: syn::Expr,
#[cfg(feature = "unstable")]
install_context: syn::Expr,
#[cfg(feature = "unstable")]
interaction_context: syn::Expr,
args: CommandArgs,
}
Expand Down Expand Up @@ -221,6 +225,7 @@ pub fn command(
let required_permissions = permissions_to_tokens(&args.required_permissions);
let required_bot_permissions = permissions_to_tokens(&args.required_bot_permissions);

#[cfg(feature = "unstable")]
fn build_install_context(
contexts: &Option<syn::punctuated::Punctuated<syn::Ident, syn::Token![|]>>,
) -> syn::Expr {
Expand All @@ -233,8 +238,10 @@ pub fn command(
}
}

#[cfg(feature = "unstable")]
let install_context = build_install_context(&args.install_context);

#[cfg(feature = "unstable")]
fn build_interaction_context(
contexts: &Option<syn::punctuated::Punctuated<syn::Ident, syn::Token![|]>>,
) -> syn::Expr {
Expand All @@ -247,6 +254,7 @@ pub fn command(
}
}

#[cfg(feature = "unstable")]
let interaction_context = build_interaction_context(&args.interaction_context);

let inv = Invocation {
Expand All @@ -258,7 +266,9 @@ pub fn command(
default_member_permissions,
required_permissions,
required_bot_permissions,
#[cfg(feature = "unstable")]
install_context,
#[cfg(feature = "unstable")]
interaction_context,
};

Expand Down Expand Up @@ -326,7 +336,9 @@ fn generate_command(mut inv: Invocation) -> Result<proc_macro2::TokenStream, dar
let dm_only = inv.args.dm_only;
let nsfw_only = inv.args.nsfw_only;

#[cfg(feature = "unstable")]
let install_context = &inv.install_context;
#[cfg(feature = "unstable")]
let interaction_context = &inv.interaction_context;

let help_text = match &inv.args.help_text_fn {
Expand Down Expand Up @@ -367,7 +379,9 @@ fn generate_command(mut inv: Invocation) -> Result<proc_macro2::TokenStream, dar
let function_generics = &inv.function.sig.generics;
let function_visibility = &inv.function.vis;
let function = &inv.function;
Ok(quote::quote! {

#[cfg(feature = "unstable")]
return Ok(quote::quote! {
#[allow(clippy::str_to_string)]
#function_visibility fn #function_ident #function_generics() -> ::poise::Command<
<#ctx_type_with_static as poise::_GetGenerics>::U,
Expand Down Expand Up @@ -417,6 +431,60 @@ fn generate_command(mut inv: Invocation) -> Result<proc_macro2::TokenStream, dar
context_menu_name: #context_menu_name,
ephemeral: #ephemeral,

__non_exhaustive: (),
}
}
});

#[cfg(not(feature = "unstable"))]
Ok(quote::quote! {
#[allow(clippy::str_to_string)]
#function_visibility fn #function_ident #function_generics() -> ::poise::Command<
<#ctx_type_with_static as poise::_GetGenerics>::U,
<#ctx_type_with_static as poise::_GetGenerics>::E,
> {
#function

::poise::Command {
prefix_action: #prefix_action,
slash_action: #slash_action,
context_menu_action: #context_menu_action,

subcommands: vec![ #( #subcommands() ),* ],
subcommand_required: #subcommand_required,
name: #command_name.to_string(),
name_localizations: #name_localizations,
qualified_name: String::from(#command_name), // properly filled in later by Framework
identifying_name: String::from(#identifying_name),
source_code_name: String::from(#function_name),
category: #category,
description: #description,
description_localizations: #description_localizations,
help_text: #help_text,
hide_in_help: #hide_in_help,
cooldowns: std::sync::Mutex::new(::poise::Cooldowns::new()),
cooldown_config: #cooldown_config,
reuse_response: #reuse_response,
default_member_permissions: #default_member_permissions,
required_permissions: #required_permissions,
required_bot_permissions: #required_bot_permissions,
owners_only: #owners_only,
guild_only: #guild_only,
dm_only: #dm_only,
nsfw_only: #nsfw_only,
checks: vec![ #( |ctx| Box::pin(#checks(ctx)) ),* ],
on_error: #on_error,
parameters: vec![ #( #parameters ),* ],
custom_data: #custom_data,

aliases: vec![ #( #aliases.to_string(), )* ],
invoke_on_edit: #invoke_on_edit,
track_deletion: #track_deletion,
broadcast_typing: #broadcast_typing,

context_menu_name: #context_menu_name,
ephemeral: #ephemeral,

__non_exhaustive: (),
}
}
Expand Down
54 changes: 36 additions & 18 deletions src/structs/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,10 @@ pub struct Command<U, E> {
pub context_menu_name: Option<String>,
/// Whether responses to this command should be ephemeral by default (application-only)
pub ephemeral: bool,
#[cfg(feature = "unstable")]
/// List of installation contexts for this command (application-only)
pub install_context: Option<Vec<serenity::InstallationContext>>,
#[cfg(feature = "unstable")]
/// List of interaction contexts for this command (application-only)
pub interaction_context: Option<Vec<serenity::InteractionContext>>,

Expand Down Expand Up @@ -199,18 +201,26 @@ impl<U, E> Command<U, E> {
builder = builder.default_member_permissions(self.default_member_permissions);
}

if self.guild_only {
builder = builder.contexts(vec![serenity::InteractionContext::Guild]);
} else if self.dm_only {
builder = builder.contexts(vec![serenity::InteractionContext::BotDm]);
}
#[cfg(feature = "unstable")]
{
if self.guild_only {
builder = builder.contexts(vec![serenity::InteractionContext::Guild]);
} else if self.dm_only {
builder = builder.contexts(vec![serenity::InteractionContext::BotDm]);
}

if let Some(install_context) = self.install_context.clone() {
builder = builder.integration_types(install_context);
if let Some(install_context) = self.install_context.clone() {
builder = builder.integration_types(install_context);
}

if let Some(interaction_context) = self.interaction_context.clone() {
builder = builder.contexts(interaction_context);
}
}

if let Some(interaction_context) = self.interaction_context.clone() {
builder = builder.contexts(interaction_context);
#[cfg(not(feature = "unstable"))]
if self.guild_only {
builder = builder.dm_permission(false);
}

if self.subcommands.is_empty() {
Expand Down Expand Up @@ -243,18 +253,26 @@ impl<U, E> Command<U, E> {
crate::ContextMenuCommandAction::__NonExhaustive => unreachable!(),
});

if self.guild_only {
builder = builder.contexts(vec![serenity::InteractionContext::Guild]);
} else if self.dm_only {
builder = builder.contexts(vec![serenity::InteractionContext::BotDm]);
}
#[cfg(feature = "unstable")]
{
if self.guild_only {
builder = builder.contexts(vec![serenity::InteractionContext::Guild]);
} else if self.dm_only {
builder = builder.contexts(vec![serenity::InteractionContext::BotDm]);
}

if let Some(install_context) = self.install_context.clone() {
builder = builder.integration_types(install_context);
if let Some(install_context) = self.install_context.clone() {
builder = builder.integration_types(install_context);
}

if let Some(interaction_context) = self.interaction_context.clone() {
builder = builder.contexts(interaction_context);
}
}

if let Some(interaction_context) = self.interaction_context.clone() {
builder = builder.contexts(interaction_context);
#[cfg(not(feature = "unstable"))]
if self.guild_only {
builder = builder.dm_permission(false);
}

Some(builder)
Expand Down

0 comments on commit 524d962

Please sign in to comment.