From ed90485fdf2bfc15e850003a7c041aa3b45d3b7c Mon Sep 17 00:00:00 2001 From: TheAwiteb Date: Mon, 25 Sep 2023 16:19:32 +0300 Subject: [PATCH] Ability to hide the command aliases from the help message --- crates/teloxide-macros/src/bot_commands.rs | 2 +- crates/teloxide-macros/src/command.rs | 6 +++- crates/teloxide-macros/src/command_attr.rs | 5 ++++ crates/teloxide-macros/src/command_enum.rs | 33 +++++++++++----------- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/crates/teloxide-macros/src/bot_commands.rs b/crates/teloxide-macros/src/bot_commands.rs index ae9b9f96..c51b2ed3 100644 --- a/crates/teloxide-macros/src/bot_commands.rs +++ b/crates/teloxide-macros/src/bot_commands.rs @@ -63,7 +63,7 @@ fn impl_descriptions(infos: &[Command], global: &CommandEnum) -> proc_macro2::To .filter(|command| command.description_is_enabled()) .map(|command @ Command { prefix, name, aliases, ..}| { let description = command.description().unwrap_or_default(); - let aliases = aliases.clone().map(|(aliases, _)| aliases).unwrap_or_default(); + let aliases = (!command.hidden_aliases).then(|| aliases.clone().map(|(aliases, _)| aliases).unwrap_or_default()).unwrap_or_default(); quote! { CommandDescription { prefix: #prefix, command: #name, description: #description, aliases: &[#(#aliases),*]} } }); diff --git a/crates/teloxide-macros/src/command.rs b/crates/teloxide-macros/src/command.rs index 9cca6987..80b763a9 100644 --- a/crates/teloxide-macros/src/command.rs +++ b/crates/teloxide-macros/src/command.rs @@ -19,6 +19,8 @@ pub(crate) struct Command { pub parser: ParserType, /// Whether the command is hidden from the help message. pub hidden: bool, + /// Whether the aliases of the command are hidden from the help message. + pub hidden_aliases: bool, } impl Command { @@ -40,6 +42,7 @@ impl Command { // FIXME: error on/do not ignore command separator command_separator: _, hide, + hide_aliases, } = attrs; let name = match (rename, rename_rule) { @@ -57,8 +60,9 @@ impl Command { let prefix = prefix.map(|(p, _)| p).unwrap_or_else(|| global_options.prefix.clone()); let parser = parser.map(|(p, _)| p).unwrap_or_else(|| global_options.parser_type.clone()); let hidden = hide.is_some(); + let hidden_aliases = hide_aliases.is_some(); - Ok(Self { prefix, description, parser, name, aliases, hidden }) + Ok(Self { prefix, description, parser, name, aliases, hidden, hidden_aliases }) } pub fn get_prefixed_command(&self) -> String { diff --git a/crates/teloxide-macros/src/command_attr.rs b/crates/teloxide-macros/src/command_attr.rs index cf5af10d..2569cae8 100644 --- a/crates/teloxide-macros/src/command_attr.rs +++ b/crates/teloxide-macros/src/command_attr.rs @@ -25,6 +25,7 @@ pub(crate) struct CommandAttrs { pub separator: Option<(String, Span)>, pub command_separator: Option<(String, Span)>, pub hide: Option<((), Span)>, + pub hide_aliases: Option<((), Span)>, } /// A single k/v attribute for `BotCommands` derive macro. @@ -53,6 +54,7 @@ enum CommandAttrKind { Separator(String), CommandSeparator(String), Hide, + HideAliases, } impl CommandAttrs { @@ -73,6 +75,7 @@ impl CommandAttrs { separator: None, command_separator: None, hide: None, + hide_aliases: None, }, |mut this, attr| { fn insert(opt: &mut Option<(T, Span)>, x: T, sp: Span) -> Result<()> { @@ -119,6 +122,7 @@ impl CommandAttrs { Separator(s) => insert(&mut this.separator, s, attr.sp), CommandSeparator(s) => insert(&mut this.command_separator, s, attr.sp), Hide => insert(&mut this.hide, (), attr.sp), + HideAliases => insert(&mut this.hide_aliases, (), attr.sp), }?; Ok(this) @@ -174,6 +178,7 @@ impl CommandAttr { "separator" => Separator(value.expect_string()?), "command_separator" => CommandSeparator(value.expect_string()?), "hide" => value.expect_none("hide").map(|_| Hide)?, + "hide_aliases" => value.expect_none("hide_aliases").map(|_| HideAliases)?, "alias" => Aliases(vec![value.expect_string()?]), "aliases" => Aliases( value diff --git a/crates/teloxide-macros/src/command_enum.rs b/crates/teloxide-macros/src/command_enum.rs index 4a3f0efa..7c1fbf4f 100644 --- a/crates/teloxide-macros/src/command_enum.rs +++ b/crates/teloxide-macros/src/command_enum.rs @@ -3,6 +3,21 @@ use crate::{ rename_rules::RenameRule, Result, }; +/// Create a if block that checks if the given attribute is applied to a enum +/// itself, if so, return an error +macro_rules! variants_only_attr { + ($($attr: ident),+) => { + $( + if let Some((_, sp)) = $attr { + return Err(compile_error_at( + concat!("`", stringify!($attr), "` attribute can only be applied to enums *variants*"), + sp, + )); + } + )+ + }; +} + pub(crate) struct CommandEnum { pub prefix: String, /// The bool is true if the description contains a doc comment @@ -25,24 +40,10 @@ impl CommandEnum { command_separator, separator, hide, + hide_aliases, } = attrs; - if let Some((_rename, sp)) = rename { - return Err(compile_error_at( - "`rename` attribute can only be applied to enums *variants*", - sp, - )); - } else if let Some((_hide, sp)) = hide { - return Err(compile_error_at( - "`hide` attribute can only be applied to enums *variants*", - sp, - )); - } else if let Some((_aliases, sp)) = aliases { - return Err(compile_error_at( - "`aliases` attribute can only be applied to enums *variants*", - sp, - )); - } + variants_only_attr![rename, hide, hide_aliases, aliases]; let mut parser = parser.map(|(p, _)| p).unwrap_or(ParserType::Default);